释放 NSArray 时将对象设置为 nil
Posted
技术标签:
【中文标题】释放 NSArray 时将对象设置为 nil【英文标题】:setting objects to nil when releasing NSArray 【发布时间】:2009-08-18 10:59:10 【问题描述】:当我收到内存警告时,我正在释放存储在 NSMutableArray 中的一堆对象。
[_children release];
我还需要在某个时候递归遍历对象(可能在发生内存警告之后),所以我需要检查对象是否仍然存在,我通过与 nil 进行比较来执行此操作 - 这是行不通的因为释放数组并没有任何东西。
我无法遍历数组,逐一删除对象并将其设置为 nil,因为我不允许在迭代期间修改数组。
感觉好像我错过了一些明显的东西。我只想释放 + nil 数组中的一些值。
【问题讨论】:
【参考方案1】:对不起,但你所做的对我来说似乎毫无意义。不能将对象设置为 nil,只能将对象的引用设置为 nil,但这会影响其他引用。
NSObject * a = [[NSObject alloc] init];
NSObject * b = a;
[a release];
a = nil;
// b is NOT nil! b still points to the memory location where
// a used to be, which is now not valid anymore and using b
// for anything may crash your application!
如果我将“a”放入数组中,然后再次从数组中删除,“a”的保留计数会减一。要么它仍然大于零,在这种情况下“a”将不被释放,要么它为零,在这种情况下它被释放。在 a 被释放后将其引用设置为 nil 对仍然指向“a”的其他变量没有影响。
因此,即使 NSArray 在将“a”的引用删除到数组并释放它之后将其设置为 nil(因为它的引用计数为零),它也不会影响仍然指向“a”的实例变量.
我不太确定你想做什么,这当然是可能的,但你在这里完全错了。
【讨论】:
感谢您的澄清。我是在错误的轨道上并找到了解决方法。我来自 C++ 背景,所以这不是很明显。在您的示例中,我会假设 b == nil 由于我不知道您真正在做什么,因此我无法提出更好的解决方案。如果数组中的对象是您自己的类,您当然可以覆盖 dealloc 方法(当保留计数达到零时调用该方法)并通知其他对象(例如委托或只是广播通知)您现在将死,所以所有其他对象可以将它们对您的引用更新为 nil。 即使在 C++ 中,如果你有一个指向对象的指针,当对象本身被销毁时,你持有的地址不会被清除 - 你会有一个无效的指针,就像 Objective-C保留计数下降到 0 并且您仍然有一个指向用于分配内存的位置的引用...【参考方案2】:假设您没有在其他地方保留数组元素,肯定是通过从数组中删除一个对象,或者释放数组本身,您也释放了元素。我认为这就是你需要做的。
来自 Apple 文档:
每个对象都会收到一条保留消息 在将其 id 添加到数组之前 以及发布消息 从数组中删除或当 数组被释放
【讨论】:
但是我怎么知道它已经发布了呢?我无法查询它,因为它不存在,它给我留下了一个悬空指针...... 因为 Apple API 是这么说的。它说如果你从数组中删除一个对象,或者释放数组 - 数组对象将被释放。 你误会了——如果 (appleAPISaysThisObjectIsReleasedOrNot()) 在运行时我不能这样做。我找到了一个解决方法,所以还是谢谢。以上是关于释放 NSArray 时将对象设置为 nil的主要内容,如果未能解决你的问题,请参考以下文章