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

我正在浏览斯科特·史蒂文森(Scott Stevenson)维护的精彩博客,我正在尝试理解一个基本的Objective-C概念,即为代理赋予“赋值”属性和“保留”属性。 注意,这两者在垃圾收集环境中是相同的。 我主要关心的是基于非GC的环境(例如:iPhone)。

直接从斯科特的博客:

“assign关键字将生成一个setter,它将值直接赋值给实例variables,而不是复制或保留它,这对于像NSInteger和CGFloat这样的原始types,或者不是直接拥有的对象,比如委托,是最好的。

这是什么意思,你不直接拥有委​​托对象? 我通常会保留我的代表,因为如果我不想让他们走进深渊,保留会照顾到我的。 我通常将UITableViewController从其各自的dataSource和委托中抽象出来。 我也保留那个特定的对象。 我想确保它永远不会消失,所以我的UITableView始终有其委托。

有人可以进一步解释我在哪里/为什么是错的,所以我可以理解Objective-C 2.0编程中使用assign属性而不是retain的常用范例吗?

谢谢!

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

A创buildB A将自己设置为B的代表… A由其所有者发布

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

你不应该担心A离开,因为它拥有B,因此在dealloc中被清除。

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

很多时候,反过来,当一个控制器将自己设置为一个视图或窗口的委托时:控制器拥有视图/窗口,所以如果视图/窗口拥有它的委托,那么这两个对象将彼此拥有。 这当然是一个保留循环,类似于具有相同结果的泄漏(应该死的物体仍然存在)。

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

无论哪种方式,具有委托的对象不应该保留它的委托。

(顺便说一句,至less有一个例外,我不记得是什么,我不认为有这个理由。)


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

如果由于某种原因而远离ARC,至lessunsafe_unretained指向对象的属性assignunsafe_unretained ,这就明确表示这是一个对对象的非保留但非归零的引用。

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

请注意,当你有一个委托,分配,这使得非常重要的是,总是将该委托值设置为零,每当对象将被释放 – 因此,一个对象应该总是小心,如果它没有dealloc委托引用在其他地方完成。

其中一个原因就是避免保留周期。 只是为了避免A和B两个对象彼此引用而且都不从内存释放的场景。

对于像NSInteger和CGFloat这样的原始types,或者不直接拥有的对象(如委托),Acutally 分配是最好的select。