Я в настоящее время работаю под предположением это -performSelector:withObject:afterDelay:
не использует поточную обработку, но планирует событие для увольнения позднее в текущий поток. Это корректно?
Больше, конкретно:
- (void) methodCalledByButtonClick {
for (id obj in array) {
[self doSomethingWithObj:obj];
}
}
static BOOL isBad = NO;
- (void) doSomethingWithObj:(id)obj {
if (isBad) {
return;
}
if ([obj isBad]) {
isBad = YES;
[self performSelector:@selector(resetIsBad) withObject:nil afterDelay:0.1];
return;
}
//Do something with obj
}
- (void) resetIsBad {
isBad = NO;
}
Этому гарантируют это -resetIsBad
не будет назван до окончания -methodCalledByButtonClick
возвраты, принимая мы работаем на основном потоке, даже если -methodCalledByButtonClick
произвольно занимает много времени для завершения?
Из docs :
Вызывает метод получателя на текущий поток с использованием значения по умолчанию режим после задержки.
Обсуждение продолжается дальше:
Этот метод устанавливает таймер для выполнения сообщение aSelector на текущем цикл выполнения потока. Таймер настроен для работы в режиме по умолчанию (NSDefaultRunLoopMode). Когда таймер срабатывает, поток пытается исключить из очереди сообщение из цикла выполнения и выполнить селектор. Успешно, если цикл выполнения работает и в режим по умолчанию; в противном случае таймер ждет, пока цикл выполнения не окажется в режим по умолчанию.
Отсюда мы можем ответить на ваш второй вопрос. Да, это гарантировано , даже с более короткой задержкой, поскольку текущий поток занят выполнением, когда вызывается performSelector
. Когда поток вернется в цикл выполнения и удалит селектор из очереди, вы вернетесь из своего methodCalledByButtonClick
.
performSelector: withObject: afterDelay:
планирует таймер в том же потоке для вызова селектора после прошедшей задержки. Если вы зарегистрируетесь в режиме выполнения по умолчанию (то есть не используйте performSelector: withObject: afterDelay: inModes:
), я считаю, что он гарантированно дождется следующего прохода через цикл выполнения, поэтому все на стек завершится первым.
Даже если вы вызываете с задержкой 0, он будет ждать до следующего цикла и вести себя так, как вы хотите. Для получения дополнительной информации см. документы .