关于ios:为什么Objective-C代表通常给予属性赋值而不是保留?

Why are Objective-C delegates usually given the property assign instead of retain?

我正在浏览由斯科特·史蒂文森维护的精彩博客,我试图理解一个基本的目标C概念,即分配代表"分配"财产与"保留"。注意,在垃圾收集环境中两者都是相同的。我主要关注的是一个非基于GC的环境(例如:iPhone)。

直接从斯科特的博客:

"assign关键字将生成一个setter,它将值直接分配给实例变量,而不是复制或保留它。这最适合于nsinteger和cgloat之类的基元类型,或者不直接拥有的对象,例如委托。"

您不直接拥有委托对象意味着什么?我通常会保留我的代表,因为如果我不希望他们进入深渊,RETAIN会帮我解决。我通常将UITableViewController从其各自的数据源和委托中抽象出来。我还保留了那个特定的对象。我想确保它永远不会消失,所以我的UITableView总是有它的委托。

有人能进一步解释我错在哪里/为什么,这样我就可以理解在Objective-c 2.0编程中使用委托的assign属性而不是retain的这种常见范例吗?

谢谢!


避免保留代理的原因是需要避免保留周期:

A创建BA将自己设置为B的委托…A由其所有者发布

如果B保留了A,A不会被释放,因为B拥有A,因此A的dealLoc永远不会被调用,导致A和B都泄漏。

你不必担心A会离开,因为它拥有B,因此会在DealLoc中将其清除。


因为发送委托消息的对象不拥有委托。

很多时候,它是相反的,就像控制器将自己设置为视图或窗口的委托:控制器拥有视图/窗口,因此如果视图/窗口拥有其委托,两个对象将彼此拥有。当然,这是一个保留循环,类似于具有相同结果的泄漏(应该是死的对象仍然活着)。

其他时候,对象是对等的:两个对象都不拥有另一个,可能是因为它们都属于同一个第三个对象。

不管怎样,带有委托的对象都不应保留其委托。

(顺便说一下,至少有一个例外。我不记得那是什么,我觉得没有什么好的理由。)

附录(增加2012-05-19):在ARC下,你应该使用weak,而不是assign。当对象死亡时,弱引用会自动设置为nil,从而消除了委托对象最终向死委托发送消息的可能性。

如果出于某种原因,您要远离ARC,至少将指向对象的assign属性更改为unsafe_unretained,这表明这是对对象的不包含但非零引用。

assign仍然适用于ARC和MRC下的非对象值。


请注意,当您有一个要分配的委托时,每当要解除分配对象时,总是将委托值设置为nil非常重要-因此,如果对象在其他地方没有这样做,则应始终小心地在解除分配中消除委托引用。


其中一个原因是为了避免保留周期。只是为了避免出现这样的情况:A和B两个对象相互引用,而没有一个对象从内存中释放出来。

Acutally分配最适合于nsinteger和cgfloat之类的基本类型,或者不直接拥有的对象,例如委托。