我正在开发一个iPhone项目,我希望从NSMutableArray中检索一个对象,从数组中删除该对象,然后再使用它。代码看起来像这样:
NSMutableArray * array;
// fill the array
NSObject * obj = [array lastObject];
[array removeLastObject];
// do something with obj (in the same function)
数组是唯一对正在访问的对象具有保留的实体。这样做安全吗?我认为这只有在lastObject自动释放对象的情况下才有效,如果有的话,这是我无法弄清楚的。
答案 0 :(得分:11)
为什么不打电话
[array removeLastObject]
在你的功能结束?这是少发布/保留的一个。它可能会使您的代码更具可读性/更少混乱。
与NSArray一样,实例 NSMutableArray保持强大 引用他们的内容。如果你 什么时候不要使用垃圾收集 你把一个对象添加到一个数组, 对象接收保留消息。什么时候 从mutable中删除一个对象 数组,它接收一个释放消息。 如果没有进一步的参考 对象,这意味着对象 被解除分配。如果你的程序保持不变 对这样一个对象的引用, 引用将变为无效,除非 您向对象发送保留消息 在它从阵列中删除之前。 例如,如果anObject不是 在将其从中移除之前保留 数组,下面的第三个声明可以 导致运行时错误:
id anObject = [[anArray objectAtIndex:0] retain];
[anArray removeObjectAtIndex:0];
[anObject someMessage];
答案 1 :(得分:3)
值得一提的是Cocoa Memory Management Rules。如果您在非GC环境中工作,例如iPhone,总是值得一提。
基本规则状态:
如果使用名称以“alloc”或“new”开头或包含“copy”(例如,alloc,newObject或mutableCopy)的方法创建对象,或者如果发送它,则获取对象的所有权保留信息。您有责任使用release或autorelease放弃您拥有的对象的所有权。在收到对象的任何其他时间,您都不能释放它。
显然,你没有使用alloc,new ...或者包含copy的东西获得obj。所以你不拥有它。
在你的代码中,第二个推论也是相关的:
通常保证收到的对象在接收到的方法中保持有效(例外包括多线程应用程序和一些分布式对象情况,尽管如果修改从中接收另一个对象的对象,也必须小心强>)。该方法也可以安全地将对象返回到其调用者
我加粗了相关部分。您已经修改了从中接收对象的数组,因此它可能会消失。您可以在将对象从数组中删除之前保留该对象,也可以在完成对象后执行删除操作。
实际上,即使你的问题中的代码,可能也是安全的,因为NSMutableArray的objectAtIndex:的实现可能会执行保留,然后在返回项目上进行自动释放。在多线程环境中,这是保证对象保持有效的足够长时间以将其返回给调用者的唯一方法。但是,我没有看到NSMutableArray的代码,所以不要依赖它。
ETA:刚看过线程编程指南,看来NSMutableAtrray没有保留,自动释放。
答案 2 :(得分:2)
NSObject * obj = [array lastObject]; // Just returns an object, its retain count not changed
[array removeLastObject]; // object receives release message
因此,如果您的数组是唯一保留您的对象的实体,那么在删除它之后,它的保留计数变为零并且应该取消分配。要安全地使用该对象,您应该保留它并在不需要时释放它:
NSObject * obj = [[array lastObject] retain];
[array removeLastObject];
// do something with obj (in the same function)
[obj release];