【发布时间】:2010-06-21 18:35:20
【问题描述】:
我有一个已保留的可变数组。
这个数组包含有很多键的字典。每个字典都包含对象。
在将字典添加到可变数组之前我是否必须保留它们,或者数组本身是否会保留添加到其中的所有内容(因为它已经保留),包括其对象在层次结构中的子对象?
谢谢。
【问题讨论】:
我有一个已保留的可变数组。
这个数组包含有很多键的字典。每个字典都包含对象。
在将字典添加到可变数组之前我是否必须保留它们,或者数组本身是否会保留添加到其中的所有内容(因为它已经保留),包括其对象在层次结构中的子对象?
谢谢。
【问题讨论】:
Foundation 容器,如NSArray 或NSDictionary,保留它直接拥有的对象,但不保留对象拥有的子对象。
例如,如果NSArray*a 包含NSArray*b,而它又包含NSArray*c,则a 保留b 和b 保留c 但a 不保留c。
也就是说,你的想法是错误的。 不正确你想知道“在将 x 传递给另一个对象 y 之前,我是否必须保留这个对象(比如 x),因为 y 可能不会保留它合适吗?” retain/release 的重点是确保对象保留和释放它拥有的对象。您相信其他对象也会这样做。
然后,如果您将对象x 放入数组y,您所要做的就是确保在它变得不必要时不要释放x(如果它不是自动释放的) 。如果y 需要它,y 会保留它,所以你不必关心它。
假设您有一个预先存在的NSMutableArray*array。然后你会用这样的方法做:
NSMutableDictionary* dictionary=[[NSMutableDictionary alloc] init];
... do something with dictionary ...
[array addObject:dictionary];
[dictionary release];
你看,如果数组需要的话,保留字典是数组的责任。它需要它,所以它保留它。你不必关心这个。
方法的职责是在方法需要时保留字典,在方法不再需要时释放它。因此,如上所示,该方法通过将其添加到数组中来释放它。
再次重申:retain/release 的全部意义在于允许您在代码中非常本地地考虑对象的生命周期。
每当您通过传递对象b 调用另一个对象a 的方法method: 时,您不必像现在一样担心method: 是否保留b,并且您不需要如果您在将b 传递给method: 之前需要保留b,则不必担心。
这是因为Cocoa框架中的每一个方法,以及你写的每一个方法,如果方法以后需要它就保留传递给它的对象b,如果它不需要它就不要保留b之后。
【讨论】:
Objective-C 容器(例如NSMutableArray)将保留添加到其中的对象。
然而,这与任何被“传播”的东西没有任何关系——无论你是否在 NSMutableArray 上调用 -retain 都无关紧要。 NSMutableArray 将简单地保留添加到其中的对象,如果这些对象本身是某种容器(例如字典),则子对象本身将已经保留添加到它们的任何内容,等等。
ps。没有真正的“保留属性”,每个对象都有一个(内部)“保留计数”。例如,如果您创建一个 NSString 并将其添加到 3 个 NSMutableArray 中,则这些数组中的每一个都将retain 它。
【讨论】: