2012年8月更新:
iOS 5和更高版本已经引入了更安全的API来处理模块使用完成块animation进/出的地方:
[self presentViewController:myModalVC animated:YES completion:^{}]; [self dismissViewControllerAnimated:YES completion:^{}];
2012年8月之前答案:
在解散模态的情况下,我遇到了类似的问题,然后快速连续地呈现模态2。 有时候,模态二会在模态被解散后显示,有时候模态二不会出现,这让我非常难过。
看起来像一个竞争条件给我…
在呈现模态2的方法的调用者上放置1+秒的延迟, showModalTwo
,使模态2每次出现在模态之后被解除:
- (void)didDismissModalOne { [self performSelector:@selector(showModalTwo:) withObject:someNumber afterDelay:1.0f]; }
这证实了一种怀疑,即解除方式之一和方式二之间存在某种竞争条件。 然而,拖延呼叫者的行为是不够的,并不能保证在其他情况下不会再出现竞赛状况。
问题
事实certificate, UIViewController
有一个公共属性, modalViewController
,当presentModalViewController:animated:
被调用时被设置,当dismissModalViewControllerAnimated:
被调用时被拆除。 modalViewController
是,它不会同步被拆除,因此可以在删除modalViewController
的旧值和按照以下方式设置新值之间创build一个竞赛。
- 现在的模态。
myViewController.modalViewController
现在指向模态
- closures模态一个。 后台进程拆除
myViewController.modalViewController
已经启动,但myViewController.modalViewController
仍然指向模态
- 现在的模态二,
myViewController.modalViewController]
现在指向模态二
- 系统callback触发,设置
myViewController.modalViewController
nil
,这中断了模态二animation的过程,结果是用户从来没有看到它。
比赛从步骤2开始并在步骤4中显现。
解决scheme
我的解决scheme是在呈现模式2的方法上放置警戒条件,以确保myViewControoler.modalViewController
在尝试呈现模式2之前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. }
像魅力一样工作。 更优雅的解决scheme可能包括超时。
发布脚本
我真的不喜欢这个解决scheme的投票方面。 @Nimrod在这个问题的被接受的答案中build议,你可以安全地从模式1的viewDidDisappear:
方法中启动模态2的表示。 我喜欢这个事件驱动方法的声音,但是在我的用例中做了一个完整的实现之后,我确认了在使用viewDidDisappear:
内部的callback来呈现模态2时,竞态条件保持viewDidDisappear:
。 要绝对确定模态2将被呈现的唯一方法是在父视图控制器内进行轮询,直到您确定self.modalViewController
nil
。 然后,只有这样才能popup模态二是“安全”的。