Как да извикате метод a.s.a.p. но най-рано в следващата итерация на цикъла?

Имам нужда от начин за запазване, за да кажа: "iOS, искам този метод да се изпълни a.s.a.p., но НЕ в ТАЗИ итерация на цикъл на изпълнение. Най-рано в следващата, но моля не в тази. Благодаря."

В момента винаги го правя така:

[self performSelector:@selector(doSomethingInNextRunLoop) withObject:nil afterDelay:0];
[self doSomeOtherThings];

С предположението, че -doSomeOtherThings винаги ще се изпълнява ПРЕДИ -doSomethingInNextRunLoop.

В документацията се казва:

Задаването на забавяне от 0 не води непременно до незабавно изпълнение на селектора. Селекторът все още е на опашка в цикъла за изпълнение на нишката и се изпълнява възможно най-скоро.

Така че по принцип може да се случи методът да бъде извикан незабавно, сякаш току-що съм изпратил директно съобщение, причинявайки -doSomethingInNextRunLoop да се изпълни преди -doSomeOtherThings?

Как мога да съм абсолютно сигурен, че ще се казва a.s.a.p. но НИКОГА в същата тази итерация на цикъл на изпълнение?

За да изясня формулировката: С run loop имам предвид основната нишка и итерацията, в която всички методи трябва да се върнат, докато нишката отново е готова за нови събития.


person openfrog    schedule 17.08.2011    source източник


Отговори (4)


Ако се притеснявате, че Apple може някой ден да даде специален случай на забавяне от 0, винаги можете да посочите забавяне от 1e-37 или така. Въпреки че документацията за performSelector:withObject:afterDelay: може лесно да се прочете, за да се гарантира, че селекторът винаги ще бъде планиран за следващата итерация на цикъл на изпълнение.

Ако се притеснявате, че Apple някой ден може да забави специални случаи по-малко от произволна долна граница, винаги можете да опитате да използвате performSelector:target:argument:order:modes:, което в документацията изрично посочва, че ще насрочи изпълнение за следващата итерация на цикъл на изпълнение.

person Anomie    schedule 17.08.2011
comment
страхотно! Категория, която да улесни това, би имала смисъл. - person openfrog; 18.08.2011

Доста тривиално използване на GCD (Grand Central Dispatch):

dispatch_async (dispatch_get_main_queue (), ^{
    NSLog (@"This stuff runs in the next iteration of the main run loop");
});
person gnasher729    schedule 18.03.2014

Мисля, че заключението ви от четенето на документацията е грешно.

Така че по принцип може да се случи методът да бъде извикан веднага, сякаш току-що съм изпратил директно съобщение

Не. Частта от документацията, която цитирате, казва, че селекторът винаги е на опашка в цикъла за изпълнение, независимо от всичко. Така че никога няма да бъде изпълнен само като директно съобщение.

Първото изречение с „не е задължително“ може да е малко подвеждащо, но мисля, че второто изречение наистина трябва да изясни, че това, от което се страхувате, няма да се случи.

person w-m    schedule 17.08.2011
comment
Надяваме се, че сте прав, защото се обзалагам, че много хора зависят от това да бъде на опашка за следващото повторение. Все пак има известна несигурност. - person openfrog; 18.08.2011

Със сигурност просто правите това;

[self doSomeOtherThings];
[self performSelector:@selector(doSomethingInNextRunLoop) withObject:nil afterDelay:0];

Което гарантира желаната от вас поръчка за изпълнение.

person Roger    schedule 17.08.2011
comment
Не винаги е удобно (или възможно) да пренаредите кода по този начин в случаи, по-сложни от този тривиален пример, използван за илюстрация. - person Anomie; 18.08.2011
comment
Не точно. Има основателни причини да изпълнявате неща в итерацията на цикъла NEXT run. Един от тях: Оставяне на потребителския интерфейс да се опреснява между тях. Подобряване на възприеманото представяне. Сред много други. Освен това Anomie е права. - person openfrog; 18.08.2011
comment
Със сигурност отговорът от Anomie удря ноктите в главата, просто отбелязвам, че в някои случаи пренареждането на кода също може да реши проблема. Малко като блокада на писателите, понякога разработчиците се спират да решават проблем по определен начин, когато всъщност има страничен план Б. FWIW Не знам за НИКАКЪВ случай, при който стандартният performSelector:withObject:afterDelay:0 води до блокиране и често използвайте техниката за оптимизиране на UI код, написан от други. - person Roger; 18.08.2011