это хорошая форма для освобождения себя в методе init, когда этот метод выделяет и возвращает что-то еще? - PullRequest
1 голос
/ 26 октября 2009

В моем коде есть что-то похожее на это:

@implementation MyClass

- (id) initWithType:(NSInteger)type {
  [self release];
  if (type == 0) {
    self = [[MyClassSubclass1 alloc] init];
  } else {
    self = [[MyClassSubclass2 alloc] init];
  }
  return self;
}
//...

@end

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

Ответы [ 2 ]

4 голосов
/ 26 октября 2009

Ваш код выглядит технически правильным с точки зрения управления памятью. Замена self другим объектом alloc'd теряет указатель на исходный объект, и никто другой не сможет освободить его, что приведет к утечке. Попробуйте закомментировать выпускной вызов и запустите его с Leaks in Instruments.

Только будьте осторожны с открытием этой конкретной банки червей - Foundation.framework (часть Cocoa) использует кластеры классов для коллекций и строк, но это довольно сложная концепция. Лучшим подходом может быть использование метода класса для каждого подкласса с использованием шаблона AbstractFactory .

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

0 голосов
/ 26 октября 2009

Это выглядит как плохое использование объектно-ориентированного дизайна.

Если вы создаете другой экземпляр в зависимости от переменной типа, то почему у вас нет подклассов для этих типов?

Было бы намного понятнее определить базовый класс со всеми общими функциями и подкласс для каждого варианта типа.

Что делает класс? Возможно, мы сможем указать вам правильное направление.

С точки зрения кода, ваш пример кода верен, но обычно это плохая практика - заменять экземпляр другим экземпляром. Если только метод init не является фабричным методом, повторно использующим экземпляры или одноэлементный инициализатор, избегайте освобождения себя вместо другого экземпляра.

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