2010-01-20 32 views
2

如果学会了如果委托的寿命比对象短,应该从对象中删除委托的困难方式。但是如果你没有对象的引用,你如何做到这一点?从未引用的对象上删除dealloc上的委托

在我的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被取消分配,并且如果用户在警报上点击“ok”,则应用程序崩溃,因为消息已发送到已发布的对象。

我通过将alert分配给vc属性解决了这个问题,所以我可以设置alert.delegate在dealloc中为零。我觉得这个解决方案不是很优雅,因为我不需要参考警报。

有没有更好的方法?

编辑:添加在斜体为澄清

回答

2

尽管通常会在不变的内容上显示警报视图。因此,如果代表在视图出现时处于活动状态,那么当它被解散时它可能还活着。如果情况并非如此,那么您必须完成您所做的工作,并且如果您不再关心它的结果,请手动取消设置警报视图的委托。

所以你关心的是alertview,因为你关心它是委托方法。问题在于,当警报解除时,代表可能不适用。所以你需要逻辑,并且为了这个逻辑,你需要保存对有问题的alert视图的引用。

换句话说,你是对的。虽然,如果UIAlertView保留它的委托,它可能会有所帮助,但它看起来好像不会在解散时崩溃。

最后,我认为警报视图阻止了所有屏幕输入?如果没有,您可以通过在出现警报时设置vc.view.userInteractionEnabled = NO使其成为真正的模式,并在解除警报时将其切换回去。这样,当警报视图启动时,用户不能关闭控制器。这听起来对我来说更加健全。

+0

我尝试设置userInteractionEnabled = NO,但在取消按钮的触摸停止仍在处理。我可能不得不参考警报方式。 –

1

从用户的角度来看,当警报视图存在,它应该要求用户的充分重视文本。也许您可以考虑在存在警报视图时禁用“取消”按钮(以及任何其他可见的非警报视图小部件),并将按钮标题添加到执行相同任务的UIAlertView实例。这将提供更清晰的用户界面,并应该整齐地解决你的内存问题。

0
-(void)delayedDismiss { 
    [self dismissModalViewControllerAnimated:YES]; 
} 

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { 
    [self performSelector:@selector(delayedDismiss) withObject:nil afterDelay:0.0]; 

} 
0

如果你不再关心UIAlertView的结果,你应该也可能关闭它在- (void) viewWillDisappear:(BOOL)animated

相关问题