Как вызвать метод как можно скорее, но в ближайшее время в следующей итерации цикла выполнения?
Мне нужен безопасный способ сказать: "iOS, я хочу, чтобы этот метод был выполнен как можно скорее, но НЕ в ЭТОЙ итерации цикла выполнения. В ближайшее время в следующем, но, пожалуйста, не в этом. Спасибо".
Прямо сейчас я всегда делаю это так:
[self performSelector:@selector(doSomethingInNextRunLoop) withObject:nil afterDelay:0];
[self doSomeOtherThings];
С предположением, что -doSomeOtherThings
всегда будет выполняться ДО -doSomethingInNextRunLoop
,
В документации сказано:
Задание задержки 0 не обязательно приводит к немедленному выполнению селектора. Селектор все еще находится в очереди в цикле выполнения потока и выполняется как можно скорее.
Так что в принципе может случиться так, что метод вызывается немедленно, как будто я только что отправил прямое сообщение, вызывая -doSomethingInNextRunLoop
быть выполненным до -doSomeOtherThings
?
Как я могу быть абсолютно уверен, что он будет называться как можно скорее, но НИКОГДА никогда не будет в той же итерации цикла выполнения?
Чтобы уточнить формулировку: Под циклом выполнения я подразумеваю основной поток и итерацию, в которой все методы должны возвращаться, пока поток снова не будет готов к новым событиям.
4 ответа
Если вы обеспокоены тем, что Apple может когда-нибудь в специальном случае отложить 0, вы всегда можете указать задержку 1e-37 или около того. Хотя документация для performSelector:withObject:afterDelay:
можно легко прочитать, чтобы гарантировать, что селектор всегда будет запланирован для следующей итерации цикла выполнения.
Если вы беспокоитесь о том, что Apple может когда-нибудь в специальном случае задержать меньше произвольной нижней границы, вы всегда можете попробовать использовать NSRunLoop performSelector:target:argument:order:modes:
что конкретно указано в документации, будет запланировано выполнение следующей итерации цикла выполнения.
Довольно тривиально, используя GCD (Grand Central Dispatch):
dispatch_async (dispatch_get_main_queue (), ^{
NSLog (@"This stuff runs in the next iteration of the main run loop");
});
Я думаю, что вы пришли к выводу, прочитав документацию неправильно.
Так что в принципе может случиться так, что метод вызывается сразу, как будто я только что отправил прямое сообщение
Нет. Часть документации, которую вы цитируете, говорит, что селектор всегда ставится в очередь в цикле выполнения, несмотря ни на что. Так что это никогда не будет выполнено просто как прямое сообщение.
Первое предложение с "не обязательно" может быть немного вводящим в заблуждение, но я думаю, что второе предложение должно действительно прояснить, что то, чего вы боитесь, не должно произойти.
Конечно, вы просто делаете это;
[self doSomeOtherThings];
[self performSelector:@selector(doSomethingInNextRunLoop) withObject:nil afterDelay:0];
Что гарантирует выполнение заказа вы хотите.