如果委托的生命周期比对象短,那么应该学习如何从对象中删除委托。但是如果你不再引用这个对象,你怎么做呢?
在我的iPhone应用程序中,我有一个视图控制器vc
,它执行异步活动并显示为模态视图。取消按钮取消模态视图。如果发生错误,则会显示UIAlertView alert
。如果用户点击确定,则alert
和模态视图都会消失。因此vc
已设置
作为alert
的代表并实施alertView:didDismissWithButtonIndex:
。像这样:
// UIViewController vc
...
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"Error"
message:@"Something went wrong"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
self.alertView = alert; // needed to unset alertView.delegate in dealloc
[alert show];
[alert release];
...
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
[self dismissModalViewControllerAnimated:YES];
}
}
通常,警报视图会阻止所有输入。不幸的是,在某些边缘情况下它没有这样做。
如果用户在警报视图出现之前触摸取消按钮 并在警报视图出现后触摸,则视图将被取消,但不会取消警报。 vc
被取消分配,如果用户在警报上点击“确定”,则应用程序崩溃,因为消息已发送到已发布的对象。
我通过将alert
分配给vc
的属性来解决这个问题,因此我可以将alert.delegate
设置为nall in dealloc。我发现这个解决方案不是很优雅,因为我真的不需要提醒警报。
有更好的方法吗?
修改:添加斜体中的文字作为说明
答案 0 :(得分:2)
尽管通常会在不变的内容上显示警报视图。因此,如果代表在视图出现时处于活动状态,则当它被解除时它可能会存活。如果情况并非如此,那么您必须完成您所做的工作,并且如果您不再关心它的结果,请手动取消设置警报视图的委托。
所以你关心alertview,因为你关心它的委托方法。皱纹是代表可能在警报被解除时不适用。因此,您需要逻辑,对于该逻辑,您需要保存对相关警报视图的引用。
换句话说,你做得对。虽然,如果UIAlertView
保留了它的委托,它可能会有所帮助,但是当它被解除时它似乎不会崩溃。
最后,我认为警报视图阻止了所有屏幕输入?如果没有,您可以通过在警报出现时设置vc.view.userInteractionEnabled = NO
并在解除警报时将其切换回来进行真正模态调整。这样,在警报视图启动时,用户无法关闭控制器。这对我来说听起来更加明智。
答案 1 :(得分:1)
从UI的角度来看,当存在警报视图时,它应该要求用户全神贯注。当存在警报视图时,您可能会考虑禁用“取消”按钮(以及任何其他可见的非警报视图窗口小部件),并向执行相同任务的UIAlertView
实例添加按钮标题。这将提供更清晰的用户界面,并且还应该整齐地解决您的内存问题。
答案 2 :(得分:0)
-(void)delayedDismiss {
[self dismissModalViewControllerAnimated:YES];
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
[self performSelector:@selector(delayedDismiss) withObject:nil afterDelay:0.0];
}
答案 3 :(得分:0)
如果您不再关心UIAlertView
的结果,您可能也应该在- (void) viewWillDisappear:(BOOL)animated