Question about factory method object lifetimes in Objective-C/Cocoa (to retain or not...)
From reading the memory management docs in the SDK, I gathered that factory methods (static constructor methods) would typically be retaining the object for me and adding it to the autorelease pool?
This would mea开发者_JAVA技巧n I have no need to retain & release an object as long as the pool does not get released before I expect? (Which should be at the end of the app, for the default autorelease pool in main()? )
This question: Cocoa Touch Question. Should [NSMutableArray array] be retained? seems to agree with this.
However when I have used the NSMutableArray arrayWithCapacity: method, I've found I have to retain the array or all heck breaks loose.
I'm sure this is all just total n00b-ness, or a bizarre bug elsewhere in the code, but if someone could explain how exactly I may have misunderstood, I'd be much obliged.
Thanks!
Update: Thanks for the answers. I think I've got it now!
From reading the memory management docs in the SDK, I gathered that factory methods (static constructor methods) would typically be retaining the object for me and adding it to the autorelease pool?
Yes, you don't have to worry about releasing objects returned from any method, except the alloc
, init
, new
, and copy
methods.
This would mean I have no need to retain & release an object as long as the pool does not get released before I expect?
Yes.
(Which should be at the end of the app, for the default autorelease pool in main()? )
No. You can only count on the object being around until you return from whichever method or function you're in. Typically, autorelease pools are flushed when control returns back to your run loop.
If you want an object instance to survive beyond the current method you must take ownership of it, by calling 'retain'. You are then also responsible for 'releasing' the instance when you no longer need it.
In your case, if you want your NSMutableArray to stick around, you need to retain
it. Better yet, use [[NSMutableArray alloc] initWithCapacity: ];
See Practical Memory Management
Usually auto-release pools are drained at the end of the current event loop. A pretty good rule of thumb is that unless you're returning an autoreleased object, if you want that object to remain outside of the current method, you should retain it.
So, when you create your NSMutableArray as an autoreleased object, once your method ends, all bets are off, and that autorelease pool could drain at any time. Retain it, and then release it in your dealloc.
Checkout this diagram below explaining the Application lifecycle. Once the application has launched, your application will be handling various events which could be user generated such as a touch, or a network activity, or one of many events. Once the event has been handled, control returns to the Event Loop
that you see below.
This event loop maintains the top level autorelease pool. In pseudocode, this event loop would look something like:
while(wait for event) {
1) create autorelease pool
2) handle event
3) release pool
}
So, whenever a event has been handled, control goes back to the main event loop, and this outer pool will be released. You should retain all objects that were created using convenience methods and will be needed even after the event handling finishes. With the extra retain count, you take ownership of the object and are responsible for releasing it when no longer needed.
iPhone Application http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Art/app_life_cycle.jpg
As soon as you add your object to the array, there is an implicit call to retain for this object, which means once added to the array you can release it from the source, and when you'll call the remove method from the array there will also be an implicit call to release.
精彩评论