我正在尝试在Objective-C中实现委托模式,但是我有时会在调用委托时遇到Bad Access异常。这似乎是由代表被释放引起的。 Apple不建议保留代表。
在尝试发送消息之前,如何检查我的代理是否仍然有效?
答案 0 :(得分:8)
如果代理人有可能被设置者释放,那么你的设计就会出现问题。您应该只对寿命比委托本身更短的对象设置委托。例如,在子视图/控制器上设置委托是可以的,因为子视图/控制器的寿命比调用者短。
AFAIK,没有可靠的方法来检测对象是否已经被释放。
答案 1 :(得分:3)
Apple没有保留代表的意思是对象不应该保留他们的代理,因为他们不拥有代理。这些只是处理消息的对象。
这并不意味着你根本不应该留下代表。创建委托的对象需要拥有它。在非GC应用程序的上下文中,这意味着它应该处理保留和释放周期,对于GC应用程序,这意味着控制器对象保持指向iVar中委托的指针。
没有看到一些代码或错误消息,很难找到这个问题的根源。
答案 2 :(得分:1)
在photoviewer应用程序中,我使用异步http来加载图像;在http下载完成之前,用户经常在调用视图控制器委托方法时导致BAD_ACCESS,从而解除当前视图(通过委托我的异步http对象引用)。我通过在视图控制器
的dealloc块中将.delegate设置为nil来解决这个问题答案 3 :(得分:1)
我也想分享我的经验,这与Nico的经历非常相似。
我一直在使用LazyTablesCode的一个修改示例,这是一个来自Apple的示例,它以异步方式加载UITableView中的图像。下载器与通过代理进行的视图之间的通信。
在我的代码中,我遇到的问题是,当应该通过委托调用的表单被释放时,有时图像的加载完成。我被迫在viewController(dealloc方法)的代码中添加这段代码:
if (self.nsDictionaryWithObjectsDownloading != nil) {
for (id theKey in self.nsDictionaryWithObjectsDownloading) {
Myobj *downloader = [self.nsDictionaryWithObjectsDownloading objectForKey:theKey];
downloader.delegate = nil;
}
}
似乎这些线路正在解决这个问题。无论如何,在做downloader.delegate = nil时,非常感谢关于它是否是一个好的解决方案或者甚至关于内存问题的意见。
谢谢和问候,