开发者

Does NSArray:lastObject return an autoreleased object?

I'm working on an iPhone project where I would like to retrieve an object from an NSMutableArray, remove the object from the array and then use it later. The code looks something like this:

NSMutableArray * array;
// fill the array
NSObject * obj = [array lastObject];
[array removeLastObject];
// do something with obj (in the same function)

array is the only entity with a retain开发者_如何转开发 on the object that is being accessed. Is this safe to do? I would assume that this would only work if lastObject autoreleased the object which is something that I can't figure out if it does.


Why not call

[array removeLastObject]

at the end of your function? That's one fewer release/retain. It might make your code more readable/less cluttered.

For the record the Apple documentation:

Like NSArray, instances of NSMutableArray maintain strong references to their contents. If you do not use garbage collection, when you add an object to an array, the object receives a retain message. When an object is removed from a mutable array, it receives a release message. If there are no further references to the object, this means that the object is deallocated. If your program keeps a reference to such an object, the reference will become invalid unless you send the object a retain message before it’s removed from the array. For example, if anObject is not retained before it is removed from the array, the third statement below could result in a runtime error:

id anObject = [[anArray objectAtIndex:0] retain]; 
[anArray removeObjectAtIndex:0]; 
[anObject someMessage];


It's worth mentioning the Cocoa Memory Management Rules here. If you are working in a non-GC environment e.g. iPhone, it's always worth mentioning them.

The fundamental rule state:

You take ownership of an object if you create it using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message. You are responsible for relinquishing ownership of objects you own using release or autorelease. Any other time you receive an object, you must not release it.

Clearly you did not obtain obj with alloc, new... or something containing copy. So you do not own it.

In your code, the second of the corollaries is also relevant:

A received object is normally guaranteed to remain valid within the method it was received in (exceptions include multithreaded applications and some Distributed Objects situations, although you must also take care if you modify an object from which you received another object). That method may also safely return the object to its invoker

I have bolded the relevant part. You have modified the array from which you received the object, so it might go away. You either retain the object before removing it from the array or do the remove after you have finished with the object.

Actually, you might be safe even with the code in your question because NSMutableArray's implementation of of objectAtIndex: might do a retain followed by an autorelease on the return item. In a multithreaded environment that would be the only way to guarantee that the object remains valid for long enough to return it to the caller. However, I've not seen the code for NSMutableArray, so do not rely on it.

ETA: Just been looking at the thread programming guide and it appears that NSMutableAtrray does not do retain, autorelease.


NSObject * obj = [array lastObject]; // Just returns an object, its retain count not changed
[array removeLastObject]; // object receives release message

So if your array is the only entity that retain your object then after removing it its retain count becomes zero and it should get deallocated. To work safely with that object you should retain it and release when it is not needed:

NSObject * obj = [[array lastObject] retain];
[array removeLastObject];
// do something with obj (in the same function)
[obj release];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜