Когда делать объект ноль и когда вызывать релиз - PullRequest
1 голос
/ 01 июня 2011

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

[objectA release];
objectA=nil;

Я читал во многих книгах, что мы должны сделать объект нулевым, оставляя представление, и освободить объект позже (в методе dealloc, конечно, этот метод вызывается после viewWillDisappear или viewDidDisappear).

Теперь я хочу знать, какой подход лучше?

Ответы [ 6 ]

5 голосов
/ 01 июня 2011

Установка на nil и освобождение - это две разные операции.

Вы release объект, чтобы отказаться от владения им.Это описано в стандартных Руководствах по управлению памятью .Если вы не знакомы с ними, вам следует прочитать их, прежде чем приступать к дальнейшему программированию на iOS.

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

Например, вы можете использовать переменную экземпляра для хранения какого-либо кеша:

- (NSArray *)items
{
    if (!cachedItems) {
        cachedItems = [[self calculateItems] retain];
    }

    return cachedItems;
}

Позже вам может потребоваться очистить этот кеш:

- (void)invalidateCache
{
    [cachedItems release];
    cachedItems = nil;
}

Нам нужно установить cachedItems равным nil, потому что наш метод items может попытаться использовать его позже.Если мы сделаем , а не и установим nil, сообщения, отправленные в (теперь освобожденный) кэш, могут привести к сбою.

Поэтому установите переменную равной nil после ее освобождения, когда это возможно.потенциально будет доступ к другим методам в вашем классе в более поздний момент времени.

2 голосов
/ 01 июня 2011

Я не думаю, что важно установить объект равным nil, но это хорошо сделать.

Если вы сделаете:

  objectA = nil;
  [objectA release];

У вас ПОТЕРЯЛ память, и этоутечка памяти.Если вы только делаете [objectA release], вы освобождаете память, но objectA по-прежнему указывает на память, поэтому, если вы попытаетесь сделать что-то вроде:

  if (objectA==nil)

Это вернет FALSE, потому что objectAНЕ ноль.Но поскольку вы делаете это почти в

  - (void)dealloc;

, вам не нужно устанавливать значение nil в этой функции.

1 голос
/ 01 июня 2011

Первый подход - это путь для вас ..

[objectA release];
objectA=nil;

Хорошей практикой также является создание объекта nil (не если вы используете его позже), потому что после освобождения объекта, если я случайно укажу на него снова, ваше приложение вылетит. Но если вы передали объекту nil и позже обратитесь к нему, в цели C он не потерпит крах (аналогичные ситуации приводили к исключению nullpointerException в таких языках, как Java)

е

[objectA doneSomeTask];

не приведет к падению, даже если objectA равен нулю. Поскольку цель C молча игнорирует обращение к нулю.

1 голос
/ 01 июня 2011

Если объект создан локально:

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

Я не читал о вашем втором подходе ни в одной книге.

Если объект является частью переменной класса и имеет retain и @synthesize:

Нижеследующее выполнит обе работы (сначала отпустите, затем назначьте функцию nil - setter ) сразу.

self.object = nil ;
0 голосов
/ 08 января 2013

Лучший способ:

[objectA release]; // sightly sightly faster since less function calls
objectA=nil;

Ленивый путь:

self.objectA=nil;

он позвонит:

(void)setObjectA:(ObjectAClass *)objectA
{
    [objectA release];         // <-- original value is released
    objectA = [objectA retain];// <-- set the point to nil and do nothing since nil
}
0 голосов
/ 01 июня 2011

То, что вы прочитали в книгах, не работает. Если вы установите для объекта значение nil, вы не сможете выпустить его позже, потому что тогда вы не сможете превзойти объект. Вы должны к первому подходу.

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