在 Objective-C 中,如果使用 mutableCopy 将 array1 复制到 array2 中,并且假设代码在 main() 中完成,那么谁负责释放数组中包含的对象?是 main() 还是 array2?
4 回答
我认为以前的答案没有抓住重点,否则提问者很不清楚。实际问题不是在谈论任何一个数组,而是在谈论数组内容:
谁负责释放数组中包含的对象?是 main() 还是 array2?
两者array1
都array2
负责释放对象。
“数组维护对其内容的强引用——在托管内存环境中,每个对象在其 id 被添加到数组之前都会收到一条保留消息,并在从数组中删除或解除分配数组时收到一条释放消息。”
首先,每个对象都由 NSArray 保留array1
。当您创建array2
via-mutableCopy
时,您会得到一个指向相同对象的 NSMutableArray,并再次保留它们中的每一个。如果array1
此时要释放,当dealloc
调用它的方法时,它会释放它包含的每个对象。但是,array2
已经保留了它们,所以对象不会被销毁——只有当它们的保留计数达到 0 时,如果array2
被销毁并且没有其他人保留任何对象(或者当它们从 中删除时array2
),就会发生这种情况。
由于集合类(数组、集合、字典等)处理保留和释放它们的内容,所以您只需要担心保留或释放集合本身。既然你用过-mutableCopy
,记住你已经隐式保留了array2
,所以你应该在用完后释放它。
我参考了这篇关于 Obj-C 内存管理的指南。他有一个关于数组和字典的部分,这是一个摘录:
数组、字典等通常会保留添加到其中的任何对象。(在处理 3rd 方集合类型对象时,请始终检查文档以查看它们是否保留)。这意味着这些集合将取得对象的所有权,并且您不需要在添加之前保留。
发帖的评论也很有用
将对象存储在数组中不会改变所有权责任。这是一个例子:
int main(int argc, char *argv[])
{
// ...
NSObject *obj1 = [[NSObject alloc] init]; // owned
NSObject *obj2 = [[NSObject alloc] init]; // owned
NSObject *obj3 = [[[NSObject alloc] init] autorelease]; // not owned
NSMutableArray *array1 = [NSMutableArray arrayWithObjects: obj1, obj2, obj3, nil]; // not owned
NSMutableArray *array2 = [array1 mutableCopy]; // owned
// ...
[array2 release];
[obj2 release];
[obj1 release];
// ...
}
此代码直接分配obj1
and obj2
,因此它拥有它们并且必须释放它们,但它是 autoreleases obj3
,因此它不必释放它们。同样,它不拥有 的结果arrayWithObjects:
,所以它不释放那个,但它确实拥有 的结果mutableCopy
,所以它必须释放那个。存储在数组中的对象是无关紧要的——您只需要关心所有权。
两个数组都保持对其内容的强引用,因此,obj1
只要数组存在就不会被释放——但这是合同的细节,它不会影响您如何管理对象或数组的所有权。obj2
obj3
NSArray
这些都是Cocoa 内存管理约定的细节,而不是数组。
将可变数组绑定到不可变数组是没有意义的。main() 将负责释放 array1。
然而,根据我的经验,释放对象只会导致应用程序崩溃。ObjC 非常擅长自动管理内存。即使运行了几个小时,我的 Cocoa 应用程序似乎也不需要比开始时更多的内存。