Потенциальная утечка объекта предупреждение - требуется уточнение - PullRequest
0 голосов
/ 03 октября 2011

После того, как я проанализировал свой код, Xcode указал на потенциальную утечку, как показано ниже. Screenshot of code with analysis results

Меня это должно беспокоить?

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

Ответы [ 4 ]

3 голосов
/ 03 октября 2011

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

Кроме того, я бы рекомендовал вам использовать стандартный alloc / init вместо new, чтобы двухфазное создание было очевидным.

Это лучше:

if (self) {
    DoublyLinkedList *dll = [[[DoublyLinkedList alloc] init] autorelease];
    self.doublyLinkedList = dll;
}

или просто

if (self) {
    self.doublyLinkedList = [[[DoublyLinkedList alloc] init] autorelease];
}
1 голос
/ 03 октября 2011

У вас есть «потенциальная утечка», потому что Анализатор видит, что вы выделили память для экземпляра DoublyLinkedList (используя new), поместили его в локальную переменную с именем dll и не освободили эту память в тот же объем.

Предполагая, что заданный вами элемент doublyLinkedList также является свойством, объявленным как retain ing, у вас также есть фактическая утечка, потому что вы чрезмерно сохранили DoublyLinkedList что вы создаете здесь.

Правила владения говорят, что у вас есть одна претензия к этому экземпляру, потому что вы вызвали new для его создания. Когда вы передаете экземпляр в setDoublyLinkedList:, он сохраняется, и у вас есть две претензии. Когда метод init заканчивается, у вас есть только одна ссылка на экземпляр через свойство ivar / - вы потеряли локальную переменную - это означает, что у вас больше заявок на владение, чем у вас есть ссылки. Это хороший признак того, что у вас будет утечка.

Чтобы устранить утечку, вам необходимо отказаться от одной из ваших претензий до окончания init метода. Это можно сделать одним из двух способов, используя release, как только свойство будет установлено:

DoublyLinkedList * dll = [DoublyLinkedList new];
[self setDoublyLinkedList:dll];
[dll release];

или autorelease:

[self setDoublyLinkedList:[[DoublyLinkedList new] autorelease]];
// Or equivalent procedures involving a temp variable

Тем не менее, следует отметить, что использование сеттеров в init может быть проблематичным (см. Также рецензия Майка Эша на тему ), поскольку средства доступа могут - потенциально - есть побочные эффекты, которые зависят от того, что ваш объект уже полностью настроен. Похоже, что есть два лагеря по этой проблеме, и, вероятно, лучше прочитать об этом и прийти к своим собственным выводам, но вы можете обнаружить, что это упрощает ваши методы инициализатора для назначения ivars вместо использования свойств:

if( self ){
    doublyLinkedList = [DoublyLinkedList new];
}

Это абсолютно правильно с точки зрения управления памятью.

Наконец, если DoublyLinkedList - это класс, код которого у вас есть, вы можете также написать вспомогательный конструктор, который вернет вам новый, автоматически выпущенный экземпляр. Соглашение в Какао состоит в том, чтобы просто назвать метод после класса со стандартным регистром имени метода, например так:

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

Обратите внимание, что это метод класса:

if( self ){
    [self setDoublyLinkedList:[DoublyLinkedList doublyLinkedList]];
}

и см. мой ответ на "Самораспределяющиеся объекты" для объяснения этих конструкторов.

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

Вы можете сделать это вместо:

if (self) {
    DoublyLinkedList *dll = [DoublyLinkedList new];
    self.doublyLinkedList = dll;
    [dll release];
}

В заголовке, объявляем doublelyLinkedList @property, который сохраняется.

0 голосов
/ 03 октября 2011

Если у вас есть свойство с именем «duplyLinkedList» (предположение, основанное на данном коде), и оно «сохраняется», вы можете сделать следующее:

if (self) {
    DoublyLinkedList *dll = [[DoublyLinkedList alloc] init]
    self.doublyLinkedList = dll;
    [dll release];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...