消息发送到解除分配的实例ARC

时间:2013-10-10 16:30:16

标签: ios objective-c delegates automatic-ref-counting

我正在做一个从服务器下载图像并将其显示在视图上的应用程序。我正在使用代表。图像完成后,加载委托会向视图发送消息以显示图像。

以上情况正常。但是,如果我从该特定视图移出到任何其他视图,则当图像加载完成时,委托会尝试发送消息并导致错误。

我尝试设置

imageFetcher.delegate=nil;

查看didUnload。在下载类中调用委托方法之前,我检查委托是否为nil。

但是我可以看到委托对象不是nil。

if(delegate!=nil)
{
  [delegate imagefetcherView:self didLoadImage:image];
}

如何解决此错误?

由于

4 个答案:

答案 0 :(得分:7)

不要依赖viewDidUnload进行任何清理。这仅在iOS 6之前的iOS版本中调用,并且仅在由于内存压力而卸载视图时才会调用(但不是在您解除/弹出视图时)。

使用nil方法或dealloc或适当的地方将您的代理人设置为viewDidDisappear

与选择nil delegate的方法相关的两个警告:

  1. 请注意,如果您推送/显示另一个视图控制器,即使当前视图控制器尚未被解除,也会调用viewWillDisappearviewDidDisappear。如果所讨论的视图控制器没有推送/呈现另一个视图控制器,则只依赖于这些与消失相关的方法。

  2. 如果使用dealloc技术,请注意,这只适用于delegate是图像提取器类的weak属性(并且委托通常应为{{1} }})。如果weakdelegatestrong属性,则会阻止视图控制器的retain被调用。

  3. 顺便说一句,我认为即使视图控制器已被解除,您仍然可以继续提取图像。您可能不仅要dealloc委托,还要取消请求。这取决于(a)您是否正在使用甚至允许取消(例如nil方法或AFNetworking操作)的提取,如果是,(b)您是否要取消它。但是,很容易占用宝贵的网络资源(特别是在缓慢的蜂窝连接上),即使用户不再需要,也可以继续请求。这取决于你的应用程序的细节。

    无论如何,不​​要依赖NSURLConnectionDataDelegate

答案 1 :(得分:3)

iOS 6 +中未调用

viewDidUnload

你应该使用这个

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
     imageFetcher.delegate=nil;
}

答案 2 :(得分:0)

您仍然可以在班级中进行dealloc调用,但不应调用[super dealloc]。如果你添加它,你可以在这里设置一个断点,看看它的保留计数在哪里。或者使用Instruments来跟踪控制器的保留/释放周期。

答案 3 :(得分:0)

我将实现一个单独的缓存来临时存储图片,护理视图控制器被解除分配,但图片可以再次使用,例如如果用户返回同一页面。

在这种情况下,您将拥有一个长期存在的缓存对象作为delegate。例如,当这些视图控制器变得可见时,视图控制器可以订阅接收有关传入图片的键值通知(只是不要忘记取消订阅viewWillDisappear中的KVO)。

如果您的控制器不可见但很可能再次显示,您将在缓存中显示图片(如果内存不足则丢弃);当然,如果您的图片永远不可能再次显示并放下图片,您也可以检查缓存。