Если вы установите делегат на нуль в классе с помощью делегата или самого класса - программирование
Подтвердить что ты не робот

Если вы установите делегат на нуль в классе с помощью делегата или самого класса

Если класс A использует класс B, а класс A является делегатом класса B, нормально ли, если делегат установлен в nil в классе B dealloc? Я видел, что код обычно сбросил делегат на нуль внутри класса A dealloc, но не был уверен, что реальная разница делает это так или иначе.

например. Это обычный способ:

// somewhere in class A

- (void) someFunc {
  self.b = [[B alloc] init];
  self.b.delegate = self;
}

- (void) dealloc {
  self.b.delegate = nil;
  [self.b release];
}
4b9b3361

Ответ 1

Да, вы должны установить свойство delegate класса B равным нулю в classA dealloc.

Это не проблема управления памятью, потому что свойства делегата должны быть отмечены как назначаемые, а не сохраняемые, чтобы избежать циклов сохранения (иначе dealloc никогда не будет вызываться). Проблема в том, что иначе classB может передать класс сообщения A после его освобождения.

Например, если классB имеет вызов delagate, чтобы сказать "быть скрытым", а classB освобождается сразу после класса A, он будет сообщать об уже отлученном классе A, вызывающем сбой.

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

Итак, да, нуль из свойства делегата в classA dealloc.

Ответ 2

Насколько мне известно, его наилучшая практика (назначить) делегата, чтобы вы избегали циклических ссылок на учетные записи для ситуаций, подобных этому. Если вы правильно настроили свойство, то есть:

@property (assign) id<BDelegate> delegate;

Вам не нужно выполнять какое-либо управление памятью в dealloc, так как счет сохранения не набит, когда вы вызываете self.b.delegate = self; - в отличие от использования (сохранения) или (копирования)

Имеют смысл? Было бы неплохо установить делегат на нуль, но в чем смысл?

Ответ 3

Во-первых, несколько наблюдений...

  • Вы забыли позвонить [super dealloc] в конце своего собственного метода dealloc.
  • Поскольку "a" создан "b", и если никакие другие объекты не сохранили "b", нет смысла в деле делегирования делегата в -dealloc, так как "b" все равно будет уничтожено. Если возможно, что другие объекты имеют ссылку на "b" (что означает, что он может пережить "a" ), установите делегат на нуль.
  • Объектом 'b' должен быть тот, кто позаботится о своем делетете в своем собственном -dealloc, если это необходимо. (Как правило, делегат не сохраняет делегата.)
  • Избегайте использования свойств в -init... и -dealloc-методах - Apple отпугивает это и не без оснований. (Не только это может иметь неожиданные побочные эффекты, но также может вызвать более неприятные, более сложные проблемы.)
  • Использование свойств (через синтаксис точек), когда вам не нужно невидимо добавлять дополнительную работу. Например, self.b.delegate = self эквивалентен [[self getB] setDelegate:self] - это просто синтаксический сахар, который делает его похожим на то, что вы напрямую обращаетесь к ivar, но на самом деле нет.
  • Использование свойств без понимания того, что они делают, может привести к проблемам. Если self.b сохраняет значение (для свойства задано значение "назначить" ), у вас есть утечка памяти на ваших руках.

Вот как я, вероятно, напишу его:

- (void) someFunc {
  b = [[B alloc] init];
  b.delegate = self; // or [b setDelegate:self];
}

- (void) dealloc {
  b.delegate = nil;
  [b release];
  [super dealloc];
}