Где выпустить копию в сеттер? - PullRequest
2 голосов
/ 30 сентября 2009

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

- (void)setName:(NSString *)newName{
    if(name != newName) {
        [name release];
        name = [newName copy];
    }
}

Мой вопрос: когда я делаю копию, где я должен ее выпустить, или я просто делаю авто-релиз? т.е.

- (void)setName:(NSString *)newName{
    if(name != newName) {
        [name release];
        name = [[newName copy] autorelease];
    }
}

1007 * Гэри *

Ответы [ 4 ]

6 голосов
/ 30 сентября 2009

Когда вы делаете copy, объект будет сохранен. Это то, что вы хотите. Если вы автоматически освободите его, со временем оно будет отменено. Итак, ваш первый пример верен. Второй сбой вашего приложения.

Если вы беспокоитесь о том, что происходит, когда объект освобождается, помните, что вы должны release любые ссылки в вашем методе dealloc.

4 голосов
/ 01 октября 2009

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

- (void)setName:(NSString *)newName{
  if(name != newName) {
      [name release];
      name = [newName copy];
  }
}

Мой вопрос: когда я делаю копию, где я должен ее выпустить, или я просто делаю авто-релиз? т.е.

- (void)setName:(NSString *)newName{
  if(name != newName) {
      [name release];
      name = [[newName copy] autorelease];
  }
}

Как я сказал на ваш другой вопрос , autorelease переводится как «отправить себя release позже». Это означает, что он считается выпуском.

Итак, ваш второй пример высвобождает старое значение name (хорошо), затем делает копию нового (хорошо), затем помещает новое в строку для выпуска (плохо), а затем помещает это сейчас обреченный объект в переменную экземпляра (очень плохо).

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

Как я уже сказал по вашему другому вопросу, я думаю, вам следует пересмотреть правила управления памятью .

1 голос
/ 01 октября 2009

Ваш первый пример верен. Как и Питер Хоси - вам лучше ознакомиться с правилами управления памятью.

Если это поможет, мой предпочтительный подход выглядит немного чище:

- (void)setName:(NSString *)name
{
  name = [name copy];
  [_name release];
  _name = name;
}
1 голос
/ 01 октября 2009

Ваш первый образец правильный:

- (void)setName:(NSString *)newName{
    if(name != newName) {
        [name release];
        name = [newName copy];
    }
}

но, как вы подозреваете, copy должен быть сбалансирован с release. Предполагая, что name имеет обычную семантику (то есть вы хотите, чтобы он оставался до тех пор, пока не будет освобожден экземпляр содержащего класса), балансировка release должна прийти в dealloc (при условии, что вы не используете сборщик мусора):

- (void)dealloc {
    [name release];
    //release other instance variables of type id

    [super dealloc];
}

Перечитайте Память Руководство по программированию для управления какао , если вы все еще в замешательстве.

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