ios 为什么Objective-C 委托通常被赋予属性assign 而不是retain?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/918698/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are Objective-C delegates usually given the property assign instead of retain?
提问by
I'm surfing through the wonderful blog maintained by Scott Stevenson, and I'm trying to understand a fundamental Objective-C concept of assigning delegates the 'assign' property vs 'retain'. Note, the both are the same in a garbage collected environment. I'm mostly concerned with a non-GC based environment (eg: iPhone).
我正在浏览由 Scott Stevenson 维护的精彩博客,我试图理解一个基本的 Objective-C 概念,即为代表分配“分配”属性与“保留”。请注意,两者在垃圾收集环境中是相同的。我最关心的是非基于 GC 的环境(例如:iPhone)。
Directly from Scott's blog:
直接来自 Scott 的博客:
"The assign keyword will generate a setter which assigns the value to the instance variable directly, rather than copying or retaining it. This is best for primitive types like NSInteger and CGFloat, or objects you don't directly own, such as delegates."
“assign 关键字将生成一个 setter,它将值直接分配给实例变量,而不是复制或保留它。这最适合像 NSInteger 和 CGFloat 这样的原始类型,或您不直接拥有的对象,例如委托。”
What does it mean that you don't directly own the delegate object? I typically retain my delegates, because if I don't want them to go away into the abyss, retain will take care of that for me. I usually abstract UITableViewController away from its respective dataSource and delegate also. I also retain that particular object. I want to make sure it never goes away so my UITableView always has its delegate around.
你不直接拥有委托对象是什么意思?我通常会保留我的代表,因为如果我不想让他们掉入深渊,保留会为我解决这个问题。我通常也将 UITableViewController 从其各自的数据源和委托中抽象出来。我也保留了那个特定的对象。我想确保它永远不会消失,所以我的 UITableView 总是有它的委托。
Can someone further explain where/why I'm wrong, so I can understand this common paradigm in Objective-C 2.0 programming of using the assign property on delegates instead of retain?
有人可以进一步解释我错在哪里/为什么,所以我可以理解在 Objective-C 2.0 编程中使用委托而不是保留的分配属性的这种常见范式吗?
Thanks!
谢谢!
采纳答案by Andrew Pouliot
The reason that you avoid retaining delegates is that you need to avoid a retain cycle:
避免保留委托的原因是您需要避免保留周期:
A creates B A sets itself as B's delegate … A is released by its owner
A 创建 B A 将自己设置为 B 的委托... A 由其所有者释放
If B had retained A, A wouldn't be released, as B owns A, thus A's dealloc would never get called, causing both A and Bto leak.
如果 B 保留了 A,A 不会被释放,因为 B 拥有 A,因此 A 的 dealloc 永远不会被调用,导致A 和 B都泄漏。
You shouldn't worry about A going away because it owns B and thus gets rid of it in dealloc.
你不应该担心 A 会消失,因为它拥有 B 并因此在 dealloc 中摆脱它。
回答by Peter Hosey
Because the object sending the delegate messages does not own the delegate.
因为发送委托消息的对象不拥有委托。
Many times, it's the other way around, as when a controller sets itself as the delegate of a view or window: the controller owns the view/window, so if the view/window owned its delegate, both objects would be owning each other. This, of course, is a retain cycle, similar to a leak with the same consequence (objects that should be dead remain alive).
很多时候,情况正好相反,当控制器将自己设置为视图或窗口的委托时:控制器拥有视图/窗口,因此如果视图/窗口拥有其委托,则两个对象将相互拥有。这当然是一个保留循环,类似于具有相同后果的泄漏(应该死的对象仍然活着)。
Other times, the objects are peers: neither one owns the other, probably because they are both owned by the same third object.
其他时候,对象是对等的:谁都不拥有另一个,可能是因为它们都由同一个第三个对象拥有。
Either way, the object with the delegate should not retain its delegate.
无论哪种方式,具有委托的对象都不应保留其委托。
(There's at least one exception, by the way. I don't remember what it was, and I don't think there was a good reason for it.)
(顺便说一下,至少有一个例外。我不记得那是什么,而且我认为没有充分的理由。)
Addendum(added 2012-05-19): Under ARC, you should use weak
instead of assign
. Weak references get set to nil
automatically when the object dies, eliminating the possibility that the delegating object will end up sending messages to the dead delegate.
附录(补充2012-05-19):根据ARC,你应该使用weak
代替assign
。nil
当对象死亡时,弱引用会自动设置为,消除委托对象最终向死委托发送消息的可能性。
If you're staying away from ARC for some reason, at least change assign
properties that point to objects to unsafe_unretained
, which make explicit that this is an unretained but non-zeroing reference to an object.
如果您出于某种原因远离 ARC,至少将assign
指向对象的属性更改为unsafe_unretained
,这明确表明这是对对象的未保留但非零引用。
assign
remains appropriate for non-object values under both ARC and MRC.
assign
仍然适用于 ARC 和 MRC 下的非对象值。
回答by Kendall Helmstetter Gelner
Note that when you have a delegate that's assign, it makes it very important to always set that delegate value to nil whenever the object is going to be deallocated - so an object should always be careful to nil out delegate references in dealloc if it has not done so elsewhere.
请注意,当您有一个分配的委托时,每当对象将被释放时,始终将该委托值设置为 nil 非常重要 - 因此,如果对象尚未释放,则应始终小心清除 dealloc 中的委托引用在别处这样做。
回答by Puneet Sharma
One of the reason behind that is to avoid retain cycles. Just to avoid the scenario where A and B both object reference each other and none of them is released from memory.
其背后的原因之一是避免保留循环。只是为了避免 A 和 B 两个对象相互引用并且它们都没有从内存中释放的情况。
Acutally assignis best for primitive types like NSInteger and CGFloat, or objects you don't directly own, such as delegates.
实际分配最适用于 NSInteger 和 CGFloat 等原始类型,或您不直接拥有的对象,例如委托。