Выпуск после удаления из массива и ссылочных указателей - PullRequest
1 голос
/ 08 августа 2009

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

Предпосылка: - У меня есть NSMutableArray объектов Tree (объект Tree знает, как рисовать себя). - У меня есть указатель ссылки (Tree * selected), который в основном указывает на дерево, к которому я последний раз прикасался. - Обратите внимание, что * выбранный указатель является слабой ссылкой.

Хорошо, пока все хорошо.

Проблема: Утечка возникает, когда я удаляю дерево. Из списка я проверяю, что удаляемое дерево высвобождает все внутри, прежде чем удалить его из массива (удаление его из массива должно автоматически вызвать release для него).

Что я пробовал: Я заметил, что моему выбранному древовидному указателю присваивается прикосновение к дереву через свойство self:

self.selected = дерево;

... и, делая это, я знаю, что это сохраняется. Итак, что я пытался сделать, это позвонить:

[self.selected release];

Я назвал это сразу после удаления дерева из массива. ... но в этот момент происходит сбой, по сути, заявив, что он уже выпущен.

Вопрос: Почему я получаю это сообщение об ошибке? Я удалил его из массива, однако мой указатель self.selected все еще имеет оставшееся количество, поэтому я не должен выпускать его?

Может быть, я должен установить его на ноль после процесса удаления? Или, может быть, я должен установить его на автоматический выпуск ДО процесса удаления?

Ответы [ 3 ]

1 голос
/ 08 августа 2009

Не пытайтесь микроуправлять сохранением / освобождением переменной selected экземпляра. Если вы хотите, чтобы selected был слабой ссылкой, объявите его с атрибутом assign:

@property(nonatomic, assign) Tree *selected;

Таким образом, оно не будет сохранено при назначении ему значения. Концептуально, это будет "контрейлер" на ссылке, которую держит ваш NSMutableArray. Поэтому, когда вы удаляете что-то из NSMutableArray, сделайте это примерно так:

if (self.selected == toBeRemoved)
    self.selected = nil;
[myArray removeObject:toBeRemoved];

Если вы не указали явно assign и ваше свойство сохраняло его содержимое, вы, скорее всего, получили исключение, потому что следующее присваивание self.selected после удаления элемента вызвало отправку другого сообщения -release старое значение, которое уже было освобождено вашим сообщением [self.selected release].

0 голосов
/ 11 августа 2009

По сути, я присваивал свои слабые ссылки, используя 'self', таким образом внутренне вызывая retain я удалил «я», и теперь все в порядке и денди. :) спасибо!

0 голосов
/ 08 августа 2009

То, что [вероятно] происходит, selected указывает на освобожденный объект, а не на ничто.

Я бы попробовал

self.selected = nil;

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

...