Право собственности на объект, после «возврата».Требуется уточнение - PullRequest
0 голосов
/ 01 октября 2011

Предполагается, что следующая декларация для класса A

@property(nonatomic, assign) DoublyLinkedList *doublyLinkedList;

, который как часть init инициализировал объект

- (id)init {
    self = [super init];
    if (self) {
        doublyLinkedList = [[DoublyLinkedList alloc] init];
    }

    return self;
}

а что за метод

- (DoublyLinkedList*) doSomethingAndReturn {

что в конечном итоге

return doublyLinkedList;

Владеет ли класс A doublyLinkedList после возврата?

Ответы [ 3 ]

2 голосов
/ 01 октября 2011

РЕДАКТИРОВАТЬ: init добавлено с alloc

Вы не звоните retain на него, но в init вы звоните alloc на него, так что он имеет счет удержания 1 - вы владеете им, и вы должны выпустить его в dealloc ,

Вы можете просто alloc выпустить его и dealloc. Вызывающий объект недвижимости может выбрать, следует ли сохранить. Другой вариант - создать объект в init, автоматически освободить его, а затем присвоить свойству с помощью (retain) вместо (assign). Таким образом, если другие места в коде alloc и присвоить этому свойству, объект, который вы alloc 'освободите. Затем в dealloc, то, на что он в данный момент назначен, будет освобождено.

Еще один вариант, если вы не хотите, чтобы другие устанавливали его, будет иметь свойство (readonly) и _doubleLinkedList iVar, а затем @synthesize doublyLinkedList = _doubleLinkedList. Затем вы можете выделить его один раз в init и знать, что никто другой не назначит его, а затем освободить его в dealloc.

Хорошая аналогия в том, что когда вы сохраняете, вы привязываете к нему поводок. Несколько предметов могут поводок для этого объекта. Он освобождается только тогда, когда все сняли поводок.

Хорошее руководство для чтения:

Руководство по программированию управления памятью Apple

В частности, из этого документа, эти правила помогают:

У вас есть любой объект, который вы создаете Вы создаете объект, используя метод имя которого начинается с «alloc», «new», «copy» или «mutableCopy» (для Например, alloc, newObject или mutableCopy).

Вы можете вступить во владение объектом, используя удержание Полученный объект обычно гарантированно остается действительным в методе получено, и этот метод также может безопасно вернуть объект Вызывающий. Вы используете сохранить в двух ситуациях: (1) В реализации метода доступа или метода init, чтобы стать владельцем объект, который вы хотите сохранить как значение свойства; и (2) для предотвращения объект признан недействительным как побочный эффект какой-либо другой операции (как объяснено в «Избегайте причинения выделения объектов, которые вы Использование»).

Когда он вам больше не нужен, вы должны отказаться от права собственности на принадлежащий вам объект Вы отказываетесь от права собственности на объект, отправив ему сообщение об освобождении или сообщение об автозапуске. В терминологии какао, поэтому отказывается от владения объектом как «освобождение» объекта.

Вы не должны уступать право собственности на объект, которым вы не владеете This это просто следствие предыдущих правил политики, изложенных в явном виде.

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

Как вы уже определили, класс A никогда не сохранял doublelyLinkedList. Так что нет, это не имеет к этому никакого отношения. На самом деле, поскольку DoublelyLinkedList не сохраняется классом A, он может быть освобожден в любой момент во время выполнения и вызвать сбой EXEC_BAD_ACCESS.

Есть два очевидных способа справиться с этим.

  1. Класс A должен сохранять DublyLinkedList во время его использования и автоматически освобождать его до того, как он его вернет.
  2. Другой «родительский» объект может сохранять как дважды, так и экземпляр класса А, и этот родительский объект должен убедиться, что «дважды» не будет освобожден, пока его использует объект класса.

Edit:

Если вы инициализируете объект при инициализации класса A, как вы добавили выше, вы должны освобождать объект только тогда, когда класс A освобожден. Это делает простой жизненный цикл объекта. Создается экземпляр класса A, он создает объект DLL. Этот объект сохраняется до тех пор, пока экземпляр класса A не будет уничтожен. Если другие объекты хотят использовать DLL, они просто запрашивают ее у экземпляра класса А. и сохраняют ее.

Цель с сохранением выпуска состоит в том, чтобы кодировать таким образом, чтобы вы могли быть уверены, что у вас есть ДАЖЕ количество сохраняемых вызовов, и выпускать вызовы для объекта. Для каждого:

- (id)init {
  self = [super init];
  if (self) {
    doublyLinkedList = [[DoublyLinkedList alloc] init];
  }

  return self;
}

Вам нужно:

-(void)dealloc {
  [super dealloc];
  [doublyLinkedList release]
}

Если ваш класс объект будет создавать и обрабатывать более одного объекта DLL, не создавайте его в -(id)init и используйте retain для объявления свойства. то:

ClassA *newClassAObject = [[ClassA alloc] init]; // create class a object
newClassAObject.doublyLinkedList = [[[DoublyLinkedList alloc] init] autorelease]; // make a DLL object, only retained by class a object.
DoublyLinkedList *dll = [newClassAObject doSomethingAndReturn]; // process the list somehow
[dll retain] // we own this now
newClassAObject.doublyLinkedList = nil; // class A object gives up interest in dll.
newClassAObject.doublyLinkedList = [[[DoublyLinkedList alloc] init] autorelease]; // now process another one.
... and on and on ...
1 голос
/ 01 октября 2011

Объекты на самом деле не "принадлежат" таким образом.Objective-C освободит память для объекта, когда количество сохраняемых данных достигнет 0. Если класс A зависит от того, поддерживается ли «doubleLinkedList» в течение всего времени существования экземпляра класса A, то объект A сохраняет дублирование, чтобы увеличить это сохранениесчитайте на 1. Когда объект A возвращает ссылку на duplyLinkedList, как вы указали выше, вызывающая сторона, которая получает этот результат, может также решить сохранить объект, что снова увеличит счет сохранения на единицу.

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

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