Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

retain and autorelease in a getter method

I am learning memory management, but I don't really understand why I should implement my attribute getter like this:

-(Weapon*)myWeapon
{
    [myWeapon retain];
    [myWeapon autorelease];
    return myWeapon;
}

I understand what I wrote, but I can't imagine why it is important? Can you please explain why I should do this?

like image 521
Malloc Avatar asked Dec 16 '22 17:12

Malloc


1 Answers

This is from the Memory Management Programming guide:

Technique 1 In technique 1, values returned by the getter are autoreleased within the calling scope:

- (NSString*) title {
    return [[title retain] autorelease];
}

- (void) setTitle: (NSString*) newTitle {
    if (title != newTitle) {
        [title release];
        title = [newTitle retain]; // Or copy, depending on your needs.
    }
}

Because the object returned from the get accessor is autoreleased in the current scope, it remains valid if the property value is changed. This makes the accessor more robust, but at the cost of additional overhead. If you expect your getter method to be called frequently, the added cost of retaining and autoreleasing the object may not be worth the performance cost.

Technique 2 Like technique 1, technique 2 also uses an autorelease technique, but this time does so in the setter method:

- (NSString*) title {
    return title;
}

- (void) setTitle: (NSString*) newTitle {
    [title autorelease];
    title = [newTitle retain]; // Or copy, depending on your needs.
}

The performance of technique 2 is significantly better than technique 1 in situations where the getter is called much more often than the setter.

Technique 3 Technique 3 avoids the use of autorelease altogether:

- (NSString*) title {
    return title;
}

- (void) setTitle: (NSString*) newTitle {
    if (newTitle != title) {
        [title release];
        title = [newTitle retain]; // Or copy, depending on your needs.
    }
}

The approach used by technique 3 is good for frequently called getter and setter methods. It is also good for objects that do not want to extend the lifetime of their values, such as collection classes. Its disadvantage is that the old value may be deallocated immediately (if there are no other owners), which will cause a problem if another object is maintaining a non-owning reference to it. For example:

NSString *oldTitle = [anObject title];
[anObject setTitle:@"New Title"];
NSLog(@"Old title was: %@", oldTitle);

If anObject was the only object that owned the original title string, then the string will be deallocated after the new title is set. The log statement would then cause a crash as oldTitle is a freed object.

EDIT: Basically the point of retaining and then auto-releasing is to ensure that the object won't get deallocated if the property value is changed before the calling scope has a chance to retain it. This isn't usually an issue unless you've got asynchronous code. In most situations - (Weapon *)myWeapon { return myWeapon; } is just fine (plus it's faster).

like image 137
Rich Avatar answered Dec 28 '22 08:12

Rich