编辑:更改为符合 Apple 的建议。此答案后面的评论指的是我的原始(并且非常糟糕)版本。以后,我会适当关注iOS 开发者库中的实用内存管理。
问题 (1):不,您不需要额外的版本。之后[[ASArray alloc] initWithArray:array]
,您的数组将有一个保留计数1
。在dealloc
中,对 的调用[_array release]
会将其返回到0
,并且应该将其释放。
如果[setArray:]
同时被调用,它将遵守其属性声明,retain
保留新对象并释放旧对象。
如果其他对象或方法保留了您的数组,则他们有责任释放它。如果您的数组的 retainCount 大于1
的开头dealloc
,则其他一些对象正在保留它,至少是暂时的。
问题 (2):您可以retainCount
在运行时检查,但正如NSObject 协议参考所警告的那样,您的对象很容易在多个自动释放池中结束,从而使其计数高得毫无意义。
奖励:您可能会认为[[NSArray alloc] initWithArray:array]
将使用其输入的保留计数和添加1
。仅当通过保留和传递对不可变源的引用来制作“副本”时才会发生这种情况,在这种情况下,其他一些对象也保留对该源的引用。 [[NSString alloc] initWithString:]
检测其来源是否不可变并执行此操作;[[NSArray alloc] initWithArray:]
才不是。 [NSArray copy]
另一方面,将保留并返回自身。
这些优化当然是特定于实现的,不应该假设。然而,构造一些对象,避免自动释放,并遵循它们的地址和retainCounts,这可能是有教育意义的,如下所示:
NSArray *array1 = [[NSArray alloc] initWithObjects:@"a", nil];
// Do not just assign array1 to [[NSArray alloc] init], or you'll get a singleton empty array with a high retain count.
// Make array1 mutable, and array2 should be copied differently.
NSLog(@"Constructed array1");
NSLog(@"array1 address = %p retainCount = %d", array1, [array1 retainCount]);
NSArray *array2 = [array1 copy];
// Use [[NSArray alloc] initWithArray:] and the results may be different.
NSLog(@"Constructed array2");
NSLog(@"array1 address = %p retainCount = %d", array1, [array1 retainCount]);
NSLog(@"array2 address = %p retainCount = %d", array2, [array2 retainCount]);
[array1 release];
NSLog(@"Released array1");
NSLog(@"array2 address = %p retainCount = %d", array2, [array2 retainCount]);
[array2 release];