从未引用的对象中删除dealloc上的委托

时间:2010-01-20 23:52:39

标签: iphone objective-c delegates

如果委托的生命周期比对象短,那么应该学习如何从对象中删除委托。但是如果你不再引用这个对象,你怎么做呢?

在我的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。我发现这个解决方案不是很优雅,因为我真的不需要提醒警报。

有更好的方法吗?

修改:添加斜体中的文字作为说明

4 个答案:

答案 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

中忽略它