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? Спасибо.
Ответы
Ответ 1
Вы должны потратить некоторое время на чтение Руководство по программированию управления памятью для Cocoa.
Короче, если вы получите свою ссылку через метод, начинающийся с "alloc" или "new" или содержащий "copy", вы владеете ссылкой и не должны ее сохранять. Вы предусмотрели его выпуск, либо через прямой выпуск, либо через авторекламу.
Если вы получаете ссылку любым другим способом (с помощью метода класса или того, что у вас есть), у вас нет ссылки, поэтому вам не нужно выпускать. Если вы хотите сохранить ссылку, вы должны ее сохранить.
В целом, это действительно довольно просто и эффективно.
Ответ 2
Хм...
Обычно я следую этому "пути".
+ (id)MyObj {
return [[[MyObj alloc] init] autorelease];
}
Освобождение объекта до его возвращения, объект будет освобожден до того, как он достигнет вызывающего объекта. Это приведет к ошибке. Избегайте этой ошибки, используя пул авторезистов. Первоначально представленный мне Скоттом Стивенсоном из Теоcocoa. Это его и многие, предпочтительный способ для Obj-C 1.0.
Ответ 3
Единственная причина, по которой вы должны выполнить код во втором примере, - это то, что имя метода начинается с нового, выделяет, создает, копирует или что-то в этом роде.
В противном случае вы несете ответственность за освобождение (или автореализацию) любого объекта, который вы выделили. Первый пример - правильный способ сделать большинство вещей.
Вызывающая функция должна сохранять значение, если оно хочет, чтобы оно продолжалось мимо области функций, но затем отвечает за ее освобождение в какой-то более поздний момент.