Я хочу построить NSOperation, у которого есть время ожидания 10 секунд после его начала и может быть закончено другим потоком в любой момент через событие. Я также использую NSOperationQueue для управления больше операций, подобных этому, и он может вычислять только один за раз (maxConcurrentOperationCount = 1). Для этого я думал о реализации с использованием dispatch_semaphore
«S, как это следующим образом:dispatch_semaphore_wait не запускается после таймаута
@implementation CustomOperation
dispatch_semaphore_t semaphore;
-(void) main {
@autoreleasepool {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(shouldFinishWaiting:) name:@"myCustomEvent" object:nil];
semaphore = dispatch_semaphore_create(0);
[self doStuff];
dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)));
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"myCustomEvent" object:nil];
}
}
-(void) shouldFinishWaiting {
NSLog(@"[WatchOperation]: Should finish waiting! %@", self);
dispatch_semaphore_signal(semaphore);
}
@end
У меня есть проблема в том, что когда-то во много раз, когда пользователь запускает приложение, первая операция не будет конца, пока событие не сработало (и это может произойти через 30 минут). Тайм-аут не принимался во внимание. Я заметил это в журналах от некоторых пользователей, поэтому я не смог воспроизвести его. Что может пойти не так, чтобы dispatch_semaphore_wait
не смог выполнить?
Позже редактирование: я ошибочно считал, что -doStuff
является асинхронным. Кажется, он not.I заменил его:
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
[self doStuff];
});
, но операция была уже на последовательную очереди "инициированный пользователем. Как я вижу, это создает еще одну совпадающую нить, это произойдет каждый раз? Это безопасно?
Что такое '-doStuff'? Это асинхронно? То есть, он запускает что-то на вторичном потоке или очереди отправки, а затем немедленно возвращается, не дожидаясь завершения чего-либо? Если это синхронно, ваш семафор бесполезен. –
Он асинхронный. Он запускает действие в одном и том же потоке и заканчивается, семафор ждет событие из другого потока. –
ОК, мой плохой ... кажется, что -doStuff был синхронным :( –