Когда выпускать переменную экземпляра - PullRequest
0 голосов
/ 31 октября 2010

В основном у меня такой сценарий:

//in interface header 
@property(nonatomic,retain)OtherClass *otherClass;

//implementation
- (id)initWithOtherClassInstance:(OtherClass*)otherClass
{ 
    if (self != [super init])
        return self;

         self.otherClass = otherClass;

    return self;
}

- (void)dealloc
{
    //Do I need to release otherClass ?
    [otherClass release];

    [super dealloc];
}

Мне интересно, должен ли я выпускать переменную экземпляра, для которой не было явно указано alloc, new или copy? Руководства по управлению памятью говорят, что я не должен этого делать, но меня беспокоит то, что self.otherClass = otherClass сохранит переменную экземпляра и, таким образом, приведет к утечке, когда я решу не выпускать ее в методе dealloc.

Более того, освобождение переменной экземпляра в методе dealloc не генерирует исключение, которое было бы в случае, если оно было перевыпущено.

Имеют ли смысл мои рассуждения здесь, и что лучше всего делать в таком случае?

Ответы [ 4 ]

1 голос
/ 31 октября 2010

Да, вам нужно выпустить это, как предлагают другие ответы. Но я нахожу, что явный вызов [foo release] на иваре, который вы сохранили через установщик свойств, немного неуравновешен. Я предпочитаю устанавливать self.otherClass = nil; в этих сценариях.

Конечно, под капотом он сделает релиз для вас, но он выглядит более сбалансированным и чистым.

0 голосов
/ 01 ноября 2010

Ваш метод инициализации неверен. Вам нужно присвоить результат [super init] себе.

Кроме того, если предположить, что self.otherClass является свойством retain, то все, что вы сделали, вроде как нормально. Если вы настаиваете на использовании свойства в -init, вы должны присвоить свойству nil в dealloc, как говорит Бен, потому что тогда, если свойство будет назначено, сохранено или скопировано, произойдет правильная вещь.

Тем не менее,

Не рекомендуется использовать методы доступа в методах -init и -dealloc. Это потому, что подклассы могут переопределять их, чтобы делать то, чего вы не ожидаете, и наблюдатели KVO могут получать уведомления в dealloc. Поэтому вам, вероятно, следует просто установить и сохранить ivar в init и выпустить его в dealloc.

0 голосов
/ 31 октября 2010

Обратите внимание, что

self.otherClass = otherClass

совпадает с

[self setOtherClass:otherClass]

Реализация по умолчанию для setOtherClass: выглядит как

- (void) setOtherClass:(OtherClass*)other
{
  [other retain];
  [otherClass release];
  otherClass = other;
}

Как видите, онасохраняет объект, поэтому вам нужно его где-то выпустить.

Если вам не нравится явное освобождение без явного выделения, нового или копирования, то вы можете сделать следующее в dealloc:

- (void) dealloc
{
  [self setOtherClass:nil];
  [super dealloc];
}
0 голосов
/ 31 октября 2010

Вы делаете это правильно, упомянутое вами правило - это правило 'create'.Вам по-прежнему необходимо сопоставлять все ваши остатки с выпусками.

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