在向委托对象发送消息之前检查其是否有效
我正在尝试在 Objective-C 中实现委托模式,但是有时在调用委托时会遇到错误访问异常。看来这是由于代表被释放造成的。 Apple 不建议保留代表。
在尝试向我的委托发送消息之前,如何检查它是否仍然有效?
I am trying to implement the delegate Pattern in Objective-C, however I am experiencing a Bad Access exception when invoking the delegate sometimes. It seems this is caused by the delegate being released. Apple does not recommend to retain delegates.
How can I check my delegate if is still valid before trying to send it a message?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果委托有可能被设置者释放,那么您的设计就有问题。您应该只在生命周期比委托本身短的对象上设置委托。例如,在子视图/控制器上设置委托就可以了,因为子视图/控制器的生命周期比调用者短。
AFAIK,没有可靠的方法来检测对象是否已经被释放。
If there's a chance that the delegate will get released by the setter, then there's something wrong with your design. You should only set delegates on objects that have a shorter lifespan than the delegate itself. For example, setting a delegate on a subview/controller is fine, because the subview/controller has a shorter lifespan than the caller.
AFAIK, there is no reliable way to detect if an object has been released already.
苹果关于不保留委托的意思是对象不应该保留它们的委托,因为它们不拥有它们。这些只是处理消息的对象。
这并不意味着您根本不应该保留代表。创建委托的对象需要拥有它。在非 GC 应用程序的上下文中,这意味着它应该处理保留和释放周期,而对于 GC 应用程序,这意味着控制器对象在 iVar 中保留指向委托的指针。
如果没有看到一些代码或错误消息,很难找到这个问题的根源。
What Apple means about not retaining delegates is that objects should not retain their delegates because they don't own them. These are only objects that handle messages.
That doesn't mean that you shouldn't retain delegates at all. The object that creates the delegate needs to own it. In the context of non-GC apps this means it should handle the retain and release cycle, and for GC apps, it means that the controller object keeps hold of a pointer to the delegate in an iVar.
without seeing some code or the error message, it is hard to find the root of this problem.
在照片查看器应用程序中,我使用异步 http 来加载图像;碰巧用户经常在 http 下载完成之前关闭当前视图(由我的异步 http 对象通过委托引用),从而在调用视图控制器委托方法时导致 BAD_ACCESS。我通过将视图控制器的 dealloc 块内的 .delegate 设置为 nil 解决了这个问题
In a photoviewer application I'm using asynchronous http to load images; it happens that the user often dismisses the current view (referenced by my async http object through a delegate) before the http download completed causing a BAD_ACCESS when calling the view controller delegate method. I solved this by setting the .delegate to nil inside the dealloc block of the view controller
我也想分享一下我的经历,这和尼科的经历非常相似。
我一直在使用 LazyTablesCode 的修改示例,该示例直接来自 Apple,并在 UITableView 中异步加载图像。下载器和通过委托生成的视图之间的通信。
在我的代码中,我遇到的问题是,有时当应该通过委托调用的表单被释放时,图像的加载就会完成。我被迫在 viewController 的代码中添加这段代码(dealloc 方法):
看来这些行正在解决问题。无论如何,对于这是否是一个好的解决方案,甚至是在执行 downloader.delegate = nil; 时的内存问题的意见,我们将非常感激。
谢谢和问候,
I'd like to share my experience also, which is very similar to Nico's one.
I've been working with a modified example of LazyTablesCode, wich is an example that comes direcly from Apple and loads images in a UITableView asynchronously. Communication between the downloader and the view it's made via delegates.
In my code, I had the problem that sometimes the load of the image finishes when the form that should be called through the delegate has been released. I've been forced to add this piece of code inside the code of the viewController (dealloc method):
It seems that these lines are solving the problem. Anyway It would be very appreciated opinions about if it's a good solution or not or even about memory issues when doing downloader.delegate = nil;
Thanks and greetings,