сохранить и авто-релиз в методе получения - PullRequest
4 голосов
/ 13 февраля 2011

Я изучаю управление памятью, но я не совсем понимаю, почему я должен реализовать свой атрибут getter:

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

Я понимаю, что я написал, но я не могу понять, почемуважный?Не могли бы вы объяснить, почему я должен это сделать?

Ответы [ 2 ]

10 голосов
/ 13 февраля 2011

Это из руководства по программированию управления памятью:

Техника 1 В методе 1 значения, возвращаемые получателем, автоматически высвобождаются в пределах вызывающей области:

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

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

Поскольку объект, возвращенный из средства доступа get, автоматически освобождается в текущей области, он остается действительным, если значение свойства изменяется. Это делает метод доступа более надежным, но за счет дополнительных накладных расходов. Если вы ожидаете, что ваш метод получения будет вызываться часто, дополнительные затраты на сохранение и автоматическое освобождение объекта могут не стоить затрат на производительность.

Техника 2 Как и в методе 1, метод 2 также использует метод автоматического выпуска, но на этот раз в методе сеттера:

- (NSString*) title {
    return title;
}

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

Производительность техники 2 значительно лучше, чем у техники 1 в ситуациях, когда геттер вызывается гораздо чаще, чем сеттер.

Техника 3 Техника 3 полностью исключает использование авто-релиза:

- (NSString*) title {
    return title;
}

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

Подход, используемый в методике 3, хорош для часто называемых методов получения и установки. Это также хорошо для объектов, которые не хотят продлевать время жизни своих значений, таких как классы коллекции. Его недостатком является то, что старое значение может быть немедленно удалено (если других владельцев нет), что вызовет проблему, если другой объект будет поддерживать ссылку на него, не являющуюся владельцем. Например:

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

Если anObject был единственным объектом, которому принадлежала исходная строка заголовка, то строка будет освобождена после установки нового заголовка. В этом случае оператор log вызовет сбой, поскольку oldTitle является освобожденным объектом.

РЕДАКТИРОВАТЬ: По сути, цель сохранения и последующего автоматического освобождения состоит в том, чтобы гарантировать, что объект не будет освобожден, если значение свойства будет изменено до того, как вызывающая область сможет его сохранить. Обычно это не проблема, если у вас нет асинхронного кода. В большинстве случаев - (Weapon *)myWeapon { return myWeapon; } просто отлично (плюс быстрее).

2 голосов
/ 13 февраля 2011

Как говорит ACBurk, здесь есть хорошее описание:

http://vgable.com/blog/2009/03/31/how-to-write-cocoa-object-getters/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...