Retain/release of returned objects

为君一笑 提交于 2019-12-04 06:25:41
hamstergene

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):

  • Method names beginning with these must return retained instances:
    • alloc
    • copy
    • new
    • retain
  • All other must return autoreleased instances.

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;
}

Generally something like

return [object autorelease];

and you can retain on the other end.

If you are planning to deploy on Lion/iOS5 or are using the latest SDK then also check out ARC.

Essentially i would recommend making the class that receives it retain it. i.e class stackoverflow receives object answer.

i.e

-(void) setAnswer:(Answer*) _answer{
    self.answer = _answer; // If the answer is created from a returned message.
    [_answer release];
}

edit: I think I might have put up the wrong stuff up there now that i am looking at it the 2nd time . Meant something along the lines:

Answer *_answer = [stackoverflow createAnswer];
self.answer = _answer;
[_answer release];

If you return an object , it is up to the owner to retain it , i would avoid autoreleases wherever possible because once the nspool kicks in, those objects are gone and if they are still used, it will cause problems.

i.e Answer *answer = [stackoverflow getAnswer] and if answer was created in the getanswer method then whomever is retrieving it is responsible in releasing it.

Makes sense?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!