I am new to Objective-C, so this might be a dumb question.
I cannot help but see the similarities between ObjC and Microsoft's COM with respect to memory management (AddRef
/Release
vs retain
/release
). In a COM environment, it's more or less imposed on you to always AddRef
(retain
) an object before returning it to the caller. From what I've seen so far (I'm a third through Cocoa® Programming for Mac® OS X (3rd Edition)), the memory management part is somewhat fuzzy.
Assuming there is no GC, what is the idiomatic way to return an object?
The basic premise behind the system is that if you want to hold on to a reference to another object, you need to issue a retain on that object. When you no longer have a use for it, you release it.
"Manual Retain-Release" or MRR In MRR, we explicitly manage memory by keeping track of objects on our own. This is implemented using a model, known as reference counting, that the Foundation class NSObject provides in conjunction with the runtime environment.
You send an object a retain message when you want to prevent it from being deallocated until you have finished using it. An object is deallocated automatically when its reference count reaches 0 .
An autorelease pool is actually a collection of objects that will be released at some point in the future (either at the end of the thread's run loop or at the end of the scope of an autorelease pool). When a pool is drained, all the objects in the pool at that time are sent the release message.
Read Memory Management Programming Guide about autorelease pools.
In Objective-C, by convention, objects should be returned autoreleased (unless the method returning the object has a name that begins with “alloc”, “new”, “copy”, or “mutableCopy”). Autoreleased objects are tracked by Objective-C in a pool and automatically handled, which means you don't need to care about sending a final release to them. This greatly simplifies reference counting compared to COM, and this is why you're not seeing any release
calls on returned objects most of the time. In contrast, the same convention specifies that all objects returned by a method whose name begins with alloc, new, copy, or mutableCopy, are the responsibility of the method caller. You have to manually call release on these objects or your program will have memory leaks.
Cocoa goes around the limitations of AddRef
/Release
in COM by introducing a third sibling; autorelease
.
retain
- I need this, make it stick around.release
- I don't need this anymore, you may remove it immediately.autorelease
- I don't need this, but let it stay around a few seconds in case someone else wants to pick it up first.This tiny addition allow most return values to be handles as-if we had garbage collection. If you are not interested in keeping the return value around, just do nothing extra.
In order to get this to work there is a convention (a convention good enough to let the compiler do the memory stuff automatically for you with upcoming ARC):
alloc
copy
new
retain
Three example implementation for how this can be applied in practice:
-(NSString*)newHelloWorldString {
NSString* s = [NSString stringWithString:@"Hello world"];
// Apply retain because s in now autoreleased
return [s retain];
}
-(NSString*)helloWorldString {
NSString* s = [[NSString alloc] initWithString:@"Hello world"];
// Apply autorelease because s is now retained.
return [s autorelease];
}
-(NSString*)fullName {
// No memory management needed, everything is autoreleased and good.
NSString* fn = [self firstName];
NSString* ln = [self lastName];
NSString* s = [NSString stringWithFormat:@"%@ %@", fn, ln];
return s;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With