Авг 2012 Обновление:
iOS 5 и выше представили более безопасные API для выполнения действий после того, как модалы анимированы в / из места с использованием блоков завершения:
[self presentViewController:myModalVC animated:YES completion:^{}];
[self dismissViewControllerAnimated:YES completion:^{}];
До августа 2012 г. Ответ:
Я столкнулся с подобной проблемой при отклонении модального первого и последующем представлении модального второго в быстрой последовательности.Иногда модальное два показывалось бы после того, как модальное было отменено, а иногда модальное два вообще не появлялось, и это меня очень огорчало.
Похоже, для меня это состояние гонки ...
Установка задержки на 1+ секунды для вызывающего метода, который представил модальное два, showModalTwo
, заставляло модальное два появляться каждый раз после отмены модального первого:
- (void)didDismissModalOne {
[self performSelector:@selector(showModalTwo:)
withObject:someNumber
afterDelay:1.0f];
}
Это подтвердило подозрение, что были некоторыесвоего рода состояние расы между увольнением модального первого и представлением модального второго.Задержка вызывающего абонента, однако, не элегантна и не гарантирует, что состояние гонки не появится снова при других обстоятельствах.
Проблема
Оказывается, UIViewController
sиметь открытое свойство modalViewController
, которое устанавливается при вызове presentModalViewController:animated:
и уничтожается при вызове dismissModalViewControllerAnimated:
.Подвох в том, что он не разрушается синхронно, поэтому можно создать гонку между удалением старого значения modalViewController
и установкой нового значения следующим образом.
- Presentмодальный.
myViewController.modalViewController
теперь указывает на модальное значение - Отклонить модальное значение.Фоновый процесс сноса
myViewController.modalViewController
запущен, но myViewController.modalViewController
неподвижное указывает на модальное одно - Текущий модальный два,
myViewController.modalViewController]
теперь указывает на модальное два - Системные вызовы обратного вызова, настройка
myViewController.modalViewController
до nil
, это прерывает процесс анимации модального два, и в результате пользователь никогда не видит его.
Гонка начинается на шаге 2 и проявляется на шаге 4.
Решение
Мое решение состояло в том, чтобы поставить условие защиты для метода, который представил модальное два, чтобы гарантировать, что myViewControoler.modalViewController
было nil
, прежде чем пытаться представить модальное два.
-(void)showModalTwo:(NSNumber *)aParameter {
if (self.modalViewController) {
[self performSelector:@selector(showModalTwo:)
withObject:aParameter
afterDelay:0.1f];
return;
}
// You can now present the second modal safely.
}
работал как шарм.Более элегантное решение может включать тайм-аут.
Post script
Мне действительно не понравился аспект опроса этого решения.@Nimrod предлагает в принятом ответе на этот вопрос, что вы можете безопасно начать презентацию модального два из метода viewDidDisappear:
модального.Мне понравился звук этого подхода, управляемого событиями, но после выполнения полной реализации в моем случае использования я подтвердил, что состояние гонки сохраняется при представлении модальных двух с использованием обратного вызова внутри viewDidDisappear:
.Единственный способ быть абсолютно уверенным в том, что будет представлен модальный номер два, - это опросить в родительском контроллере представления, пока вы не будете абсолютно уверены, что self.modalViewController
равно nil
.Тогда и только тогда это "безопасно", чтобы совать модальные два.