Objective c 在发送消息之前检查有效的委托对象

Objective c 在发送消息之前检查有效的委托对象,objective-c,cocoa,delegates,retain,Objective C,Cocoa,Delegates,Retain,我试图在Objective-C中实现委托模式,但有时调用委托时遇到错误的访问异常。这似乎是由于代理被释放造成的。苹果不建议保留代表 在尝试发送消息之前,如何检查我的代理是否仍然有效?如果该代理有可能被setter释放,则说明您的设计有问题。只应在比代理本身寿命短的对象上设置代理。例如,在子视图/控制器上设置委托是可以的,因为子视图/控制器的寿命比调用者短 顺便说一句,没有可靠的方法来检测对象是否已经被释放。苹果关于不保留代理的意思是,对象不应该保留它们的代理,因为它们不拥有它们。这些只是处理消息

我试图在Objective-C中实现委托模式,但有时调用委托时遇到错误的访问异常。这似乎是由于代理被释放造成的。苹果不建议保留代表


在尝试发送消息之前,如何检查我的代理是否仍然有效?

如果该代理有可能被setter释放,则说明您的设计有问题。只应在比代理本身寿命短的对象上设置代理。例如,在子视图/控制器上设置委托是可以的,因为子视图/控制器的寿命比调用者短


顺便说一句,没有可靠的方法来检测对象是否已经被释放。

苹果关于不保留代理的意思是,对象不应该保留它们的代理,因为它们不拥有它们。这些只是处理消息的对象

这并不意味着你不应该保留代表。创建委托的对象需要拥有它。在非GC应用程序的上下文中,这意味着它应该处理保留和释放周期,对于GC应用程序,这意味着控制器对象在iVar中保持指向委托的指针


如果没有看到一些代码或错误消息,就很难找到问题的根源。

在photoviewer应用程序中,我使用异步http加载图像;在http下载完成之前,用户通常会关闭当前视图(由我的异步http对象通过委托引用),从而在调用view controller委托方法时导致错误的_访问。我通过在视图控制器的dealoc块中将.delegate设置为nil解决了这个问题,我也想分享一下我的经验,这与Nico的经验非常相似

我一直在使用LazyTablesCode的一个修改示例,它直接来自Apple,异步加载UITableView中的图像。下载程序与通过代理生成的视图之间的通信

在我的代码中,我遇到了这样的问题:当应该通过委托调用的表单被释放时,图像的加载有时会结束。我被迫将这段代码添加到viewController的代码中(dealloc方法):

这些线路似乎正在解决问题。不管怎么说,当下载时,对于它是否是一个好的解决方案,或者甚至是关于内存问题,我们都非常感谢您的意见。delegate=nil


感谢和问候,

若要查看对象是否已完全释放,请在类的
dealloc
finalize
方法中发送日志消息。@Abizem:在这种情况下,这没有帮助。问题是您是否可以检测对象是否已释放(解除分配)。如果没有对象本身的配合,我认为这是不可能的。我的意思是,类在完全释放时发送日志消息。可以设置一个生命周期更短的委托,您只需确保委托给的对象在其dealloc方法中将委托设置为nil。只有在您可以在不同的线程上获得委托回调而不是解除委托的情况下,才会发生这种情况。如果您有多线程代码,其中您正在销毁其他线程仍在使用的东西,那么您已经有了更大的设计缺陷。您可能希望取消并释放异步HTTP下载对象,尤其是如果您的应用程序是针对iPhone的。应用商店的审查者不会善待过度的带宽使用,例如当你的应用程序在用户退出后继续下载图像时。理想情况下,将部分文件保存在临时文件目录中,如果用户返回图像,则继续下载。我发现,到目前为止,nilling委托是最好的实用答案。然而,菲利普有一些非常好的观点。
if (self.nsDictionaryWithObjectsDownloading != nil) {
    for (id theKey in self.nsDictionaryWithObjectsDownloading) {
        Myobj *downloader = [self.nsDictionaryWithObjectsDownloading objectForKey:theKey];
        downloader.delegate = nil;
    }
}