我无法理解为什么用弱指针定义一个委托是正确的:
@property (nonatomic,weak) id delegate;
我无法理解为什么没有必要保留对委托的引用...我不希望我用作委托的对象被释放...因此,我宁愿使用强大的参考不是弱者!
在许多情况下,委托是创建我的类实例的同一个对象,在这种情况下,创建一个弱引用将是避免保留周期的一个很好的解决方案......但是如果我选择一个完全不同的对象怎么办?作为代表?
我搜索了有关堆栈溢出的其他问题,但我找不到可以帮助我完全理解这种情况的东西。
答案 0 :(得分:91)
对象弱保留其委托的原因是避免保留周期。想象一下以下场景:对象a
创建b
并保留它,然后将自己设置为b
的委托。 {0}已由其所有者发布,保留周期包含a
和a
。这实际上是一种非常常见的情况。考虑一个视图控制器,它拥有一个视图并充当该视图的委托。在这种情况下,视图不应该保留控制器 - 作为适当的MVC架构的一部分,并防止保留周期。
答案 1 :(得分:26)
虽然保留周期是一个有效的问题,但弱引用的推理更多地与苹果关于如何使用uikit和开箱即用的其他元素的委托模式的观点有关:
具体做法是: “委托的主要价值在于它允许您轻松地在一个中心对象中自定义多个对象的行为。”
如果委托处理管理多个对象的委托任务,那么这些对象不需要保留委托,也不应承担委托委托的责任,因为它可能被其他对象使用。弱引用强制执行代表管理不是委托人责任的概念。
目标c中的一个示例是一个用于多个表视图的委托,例如使用表视图和带有uisearchbar的searchdisplaycontroller时。 Apples示例使用控制器作为委托,但是当您为搜索的主表视图和结果表视图使用一个自定义委托时,推理仍然成立。您的控制器可能会保留该自定义委托,以便提供给两个表视图。
这与其他语言中引用的基本委派模式有根本的不同,其中委托通常由委托者创建,每个实例可以管理自己的委托实例。
答案 2 :(得分:18)
这是为了避免保留周期。 Apple提供有关advanced memory management的信息性指南,解释情况以及如何最好地处理它。在ARC中,它们现在称为强引用循环,在Transitioning to ARC Release Notes中对此进行了解释。
以前你要为这样的委托定义一个属性,
@property (nonatomic, assign) id delegate;
但是在ARC中,你可以这样定义它,
@property (nonatomic, unsafe_unretained) id delegate;
或者,例如,如果您有一个名为<MyObjectDelegate>
的协议,您也可以这样定义委托,
@property (nonatomic, weak) id <MyObjectDelegate> delegate;
换句话说,如果你有一个协议,你可以在ARC中声明一个委托weak
。否则,unsafe_unretained
。
答案 3 :(得分:3)
作为一种常见做法,如果我们有两个对象相互保持引用,我们将“父子关系”中的“子”对象作为弱引用。
对于iOS中的委派模式,委托对象是父对象,因为没有委托对象就不需要委托调用者。例如,您有一个句子对象,其中包含方法sentenceShouldEnd的委托对象。段落对象是句子对象的委托对象。显然段落对象实际上是父对象,在你的句子对象中你应该将你的委托作为弱引用。
在你的观点,你将代表分配给自己,你的理解是错误的。我们永远不应该委托给自己。如果您觉得有必要聘请代理商为您购买机票,为什么还要自己购票?你说的是两个完全不同的概念。当您将委托对象定义为属性时,它在其定义的对象中使用弱引用(假设为A,即委托对象是A的属性)。当你初始A(让我们说在B中)时会分配代表,那么很可能你会将A.delegate分配给self,这是真实的B.你在这里看到了亲子关系?你在B中为A分配内存。你在B中持有A.没有B,A不存在。你没有将代表分配给A !!!!