Подтвердить что ты не робот

Objective-C управление памятью - лучшие практики при возврате объектов?

Предположим, что у меня есть такая функция:

- (NSSet *) someFunction {
    //code...
    return [[[NSSet alloc] initWithObjets:obj1, obj2, nil] autorelease];
}

Когда я вызываю эту функцию, мне нужно сохранить/вернуть возвращаемое значение? Я предполагаю, что знаю.

Однако, если я не делаю autorelease, поэтому someFunction теперь выглядит следующим образом:

- (NSSet *) someFunction {
    //code...
    return [[NSSet alloc] initWithObjets:obj1, obj2, nil];
}

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

Мой вопрос: какова предлагаемая/лучшая практика для таких ситуаций? Рекомендуется ли использовать одну или другую версию someFunction? Спасибо.

4b9b3361

Ответ 1

Вы должны потратить некоторое время на чтение Руководство по программированию управления памятью для Cocoa.

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

Если вы получаете ссылку любым другим способом (с помощью метода класса или того, что у вас есть), у вас нет ссылки, поэтому вам не нужно выпускать. Если вы хотите сохранить ссылку, вы должны ее сохранить.

В целом, это действительно довольно просто и эффективно.

Ответ 2

Хм...

Обычно я следую этому "пути".

+ (id)MyObj {
  return [[[MyObj alloc] init] autorelease];
}

Освобождение объекта до его возвращения, объект будет освобожден до того, как он достигнет вызывающего объекта. Это приведет к ошибке. Избегайте этой ошибки, используя пул авторезистов. Первоначально представленный мне Скоттом Стивенсоном из Теоcocoa. Это его и многие, предпочтительный способ для Obj-C 1.0.

Ответ 3

Единственная причина, по которой вы должны выполнить код во втором примере, - это то, что имя метода начинается с нового, выделяет, создает, копирует или что-то в этом роде.

В противном случае вы несете ответственность за освобождение (или автореализацию) любого объекта, который вы выделили. Первый пример - правильный способ сделать большинство вещей.

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