Какой из этих методов управления памятью лучше в каких ситуациях?

В Руководстве по программированию управления памятью Apple показано, три официально санкционированных метода написания методов доступа, которые должны сохранять или освобождать ссылки на объекты.

В случае первых двух методов (воспроизведенных ниже) в документации Apple говорится, что «[t] производительность метода 2 значительно выше, чем у метода 1, в ситуациях, когда геттер вызывается гораздо чаще, чем сеттер».

// Technique 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.
    }
}

// Technique 2
- (NSString*) title
{
    return title;
}

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

Является ли это единственной разницей между техникой 1 и техникой 2, или использование одного метода по сравнению с другим имеет другие тонкие последствия, о которых мне, возможно, нужно знать? И если метод 2 использует более производительный метод получения, следует ли из этого, что метод 1 использует более производительный метод установки, поскольку title получает явный (и предположительно немедленный) выпуск?


person Jonathan    schedule 08.01.2011    source источник


Ответы (2)


Получатель из 2 и установщик из 1:

- (NSString*) title
{
    return title;
}

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

Второй метод получения хрупок (он выйдет из строя, если кто-то получит доступ к title объекта, а затем освободит объект), поэтому первый обычно предпочтительнее, даже если он немного медленнее.

Первый установщик более эффективен и будет работать даже в ситуациях, когда пул автозапуска не существует, поэтому это предпочтительнее. Причина, по которой он более эффективен, заключается не только в автоматическом выпуске по сравнению с выпуском - он вообще не работает, если вы пытаетесь установить для свойства его существующее значение.

person Chuck    schedule 08.01.2011
comment
Если метод dealloc правильно очищает переменные с помощью средств доступа, тогда второй метод не вызовет сбоя, потому что заголовок будет выпущен автоматически, а второй установщик работает быстрее, когда новый заголовок отличается. Тем не менее, он использует больше памяти, поскольку старое название не выпускается сразу. - person ughoavgfhw; 09.01.2011
comment
@ughoavgfhw: Использование аксессоров в dealloc неуместно и фактически считается плохой практикой Apple и большинством программистов Cocoa, о которых я слышал комментарии по этому поводу. - person Chuck; 10.01.2011
comment
Доступ @chuck к геттеру из метода 1 и последующее освобождение также вызовет сбой. - person Remover; 13.01.2011
comment
@Remover: С какой стати это могло вызвать аварию? - person Chuck; 13.01.2011
comment
@chuck, потому что после автозапуска счетчик удержания должен быть таким же, как и для метода 2. так что выпуск также потенциально может вызвать сбой, не так ли? но просто подумайте об этом сейчас ... не должно быть никаких проблем, если объект уже сохранен до получения. пожалуйста, поправьте меня, если я ошибаюсь ... - person Remover; 18.01.2011
comment
@Remover: счетчик удержания должен быть на единицу выше, чем для метода 2, из-за удержания. Автозапуск не освобождает объект немедленно и, следовательно, не приводит к уменьшению его счетчика удержания - он просто добавляет его в пул автозапуска. Объект фактически не будет выпущен, пока бассейн не будет осушен. Таким образом, даже если содержащий объект освобожден, значение, возвращаемое методом получения метода 1, все равно будет сохраняться до тех пор, пока пул автозапуска не будет опустошен (обычно на следующей итерации цикла событий). Таким образом, никакого сбоя. - person Chuck; 18.01.2011
comment
@chuck: но в конечном итоге объекту в пуле автозапуска будет отправлено 1 сообщение о выпуске (потенциально) слишком много, что приведет к сбою. в чем суть. - person Remover; 18.01.2011
comment
@Remover: Я не знаю, откуда пришло слишком много сообщений о выпуске. Я не говорил о чрезмерном освобождении. Я говорил о том, что свойство объекта высвобождается вместе с объектом, хотя свойство все еще используется в окружающем контексте. Например: Foo *foo = [Foo new]; NSString *name = [foo name]; [foo release]; return [name stringByAppendingString:@" is my name"]; - вылетает при использовании геттера 2, отлично работает с геттером 1. - person Chuck; 19.01.2011
comment
@chuck: ага! вот откуда взялся весь этот ужасный беспорядок ... тогда это проясняет. - person Remover; 19.01.2011