【发布时间】:2010-11-08 10:20:22
【问题描述】:
在 Objective-C 中,如果使用 mutableCopy 将 array1 复制到 array2,并且假设代码在 main() 中完成,那么谁负责释放数组中包含的对象?是main()还是array2?
【问题讨论】:
标签: objective-c cocoa memory-management nsarray
在 Objective-C 中,如果使用 mutableCopy 将 array1 复制到 array2,并且假设代码在 main() 中完成,那么谁负责释放数组中包含的对象?是main()还是array2?
【问题讨论】:
标签: objective-c cocoa memory-management nsarray
我认为以前的答案没有抓住重点,否则提问者很不清楚。实际问题不是在谈论任何一个数组,而是在谈论数组内容:
谁负责释放数组中包含的对象?是main()还是array2?
array1 和array2 都负责释放对象。
“数组维护对其内容的强引用——在托管内存环境中,每个对象在其 id 被添加到数组之前都会收到一条保留消息,当它从数组中删除时或在数组中删除时会收到一条释放消息被释放。”
首先,每个对象都由 NSArray array1 保留。当您通过-mutableCopy 创建array2 时,您会得到一个指向相同对象的NSMutableArray,并再次保留它们中的每一个。如果此时你要释放array1,当它的dealloc 方法被调用时,它会释放它包含的每个对象。但是,array2 保留了它们,因此对象不会被销毁 - 只有当它们的保留计数达到 0 时,如果 array2 被销毁并且没有其他人保留任何对象(或者当它们被删除时,就会发生这种情况来自array2)。
由于集合类(数组、集合、字典等)处理保留和释放它们的内容,您只需担心保留或释放集合本身。由于您使用了-mutableCopy,请记住您已经隐式保留了array2,因此您应该在完成后释放它。
【讨论】:
我在 Obj-C 中引用 this guide 的内存管理。他有一个关于数组和字典的部分,摘录如下:
数组、字典等通常会保留添加到其中的任何对象。 (在处理 3rd 方集合类型对象时,请始终检查文档以查看它们是否保留)。这意味着这些集合将取得对象的所有权,并且您不需要在添加之前保留。
发帖的cmets也很有用
【讨论】:
将对象存储在数组中不会改变所有权职责。这是一个例子:
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和obj2,所以它拥有它们并且必须释放它们,但是它自动释放obj3,所以它不必释放它们。同样的,它不拥有arrayWithObjects: 的结果,所以它不释放它,但它拥有mutableCopy 的结果,所以它必须释放它。存储在数组中的对象是无关紧要的——您只需要关心所有权。
两个数组都保留对其内容的强引用,因此只要数组存在,obj1、obj2 和 obj3 就不会被释放 - 但这是 NSArray 合约的细节,它不会' 不会影响您管理对象或数组的所有权的方式。
这些都是Cocoa's memory management conventions 的详细信息,而不是数组。
【讨论】:
将可变数组绑定到不可变数组是没有意义的。 main() 将负责释放 array1。
然而,根据我的经验,释放对象只会导致应用程序崩溃。 ObjC 非常擅长自动管理内存。即使运行了几个小时,我的 Cocoa 应用程序似乎也不需要比开始时更多的内存。
【讨论】: