编辑
我只记得几周前的另一个类似问题。您遇到了竞争状况,这可能可以使用GCD(Grand Central Dispatch)解决。这类似于@rakeshNS 建议的解决方案,但危险性较小。(使用计时器来处理竞争条件是不好的做法,尽管在许多语言中调用具有 0 秒计时器等待时间的方法是一种用于将该方法调用放在调用堆栈末尾的技巧,也就是使其异步)。苹果为此提供了一种机制。
我会尝试做这个轻微的编辑:
[customAlertLoad dismissViewControllerAnimated:NO completion:^{
dispatch_async(dispatch_get_main_queue(), ^(void) {
CustomAlertMsg *cust = [[CustomAlertMsg alloc] init];
cust.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
cust.modalPresentationStyle = UIModalPresentationFormSheet;
cust.delegate = self;
[self.navigationController presentModalViewController:cust animated:YES];
cust.view.superview.frame = CGRectMake(0, 0, 458, 230);
cust.view.superview.center = self.view.center;
});
}];
对 dispatch_async 的调用将块放在执行堆栈的末尾。在模式被解除之前,它无法运行。这也允许在两个模态的解除和呈现上制作动画。
然而,我应该提到,在这个特定的问题中,这是一个 hack。 你在其他地方有问题。如果我在测试项目中重现您的设置,我可以从完成块中创建/关闭任意数量的模式,而不会遇到您的错误(只要从用于关闭模式的自定义委托回调中调用解除代码,就像苹果建议的那样)。我会查看您的自定义警报负载和自定义警报类代码。
结束编辑
这可能与您的问题不同,在将我的代码库移动到 ARC 之后,我之前遇到过弹出窗口的问题。在我的 Popover 发布得太早或保留时间过长的情况下发生了奇怪的事情。解决方案是创建一个实例变量来保存 Popover,并手动管理它。然后一切都开始工作了。
所以我会这样做:
@interface YourClass:UIViewController
@property (nonatomic,strong) CustomAlertMsg *cust;
@end
@implementation YourClass
... Codey Code....
-(void)pushView{
// For the sake of sanity, nil the modal here
if(self.cust != nil) self.cust = nil;
self.cust = [[CustomAlertMsg alloc] init];
self.cust.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
self.cust.modalPresentationStyle = UIModalPresentationFormSheet;
self.cust.delegate = self;
[self.navigationController presentModalViewController:self.cust animated:YES];
self.cust.view.superview.frame = CGRectMake(0, 0, 458, 230);
self.cust.view.superview.center = self.view.center;
}
// Then where you dismiss it, or in the delegate callback that is
// called when you dismiss it, if you are using one anyway,
// nil it out
- (void)methodThatDismissesModal
{
[self dismissModalViewControllerAnimated:YES];
// This is pretty important
if(self.cust != nil) self.cust = nil;
}
... Codey Code....
@end