iOS开发中,委托(delegate)几乎被广泛应用。
对于像这样的委托,我们需要使用 "assign" 而不是 "retain"。
@property(assign) id delegate;
避免循环引用问题是原因。为什么Objective-C代理通常使用属性assign而不是retain?
我看到很多代码仍在使用“retain”。那么这里的问题是,如果我们为委托使用retain,我们是否仍会遇到循环引用问题?谢谢。
iOS开发中,委托(delegate)几乎被广泛应用。
对于像这样的委托,我们需要使用 "assign" 而不是 "retain"。
@property(assign) id delegate;
避免循环引用问题是原因。为什么Objective-C代理通常使用属性assign而不是retain?
我看到很多代码仍在使用“retain”。那么这里的问题是,如果我们为委托使用retain,我们是否仍会遇到循环引用问题?文档中提到:
保留一个对象会创建一个强引用,只有在所有的强引用被释放之后该对象才能被释放。如果两个对象互相保留,它们中的任何一个都无法被释放,因为它们之间的连接无法被断开。
例如,考虑一个实现了 UITableViewDelegate 协议的 UITableViewController。UITableView 被它的视图控制器持有,尽管 UITableView 不保留它的代理。
如上所述的文档,UITableViewController 只有在所有强引用被释放时才能完成其析构。由于将 UITableViewController 作为代理的UITableView不保留它,当UItableViewController 的拥有者调用 release 方法时,引用计数将变为零并且 dealloc 方法将被调用。
现在假设 UITableView 保留它的代理。UITableViewController 将至少具有 +2 的保留计数。一种来自它的拥有者,另一种来自 UITableView。当 UITableViewController 的拥有者对其调用 release 方法时,引用计数将变为 +1,并且不像预期的那样降为零,因此 dealloc 方法直到引用计数达到零时才会被调用。要使引用计数达到零,UITableViewController 需要释放它的 UITableView,然后UITableView 将释放它的代理 (UITableViewController)。因为 UITableViewController 只有在 dealloc 时才会处理它的视图 (UITableView),而此时这种情况永远不会发生,因为保留计数不会降至 +1 以下。
(让我们不考虑内存警告和任何其他可能的情况...我只是注意到 ViewController / View 不是此示例的最佳选项,但我已经写了太多了。 :))
这有意义吗?