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