Если вы установите для делегата значение nil в классе, используя делегат или в самом классе

Если класс A использует класс B, а класс A является делегатом класса B, это нормально, если для делегата в ноль класса B установлено значение nil? Я видел код, обычно сбрасывающий делегата в ноль внутри 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];
}

Ответы на вопрос(3)

вы должны установить свойство делегата classB равным nil в dealloc classA.

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

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

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

Так что да, вычеркните свойство делегата из разметки класса

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

Вот как бы я это написал:

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

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

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

@property (assign) id<BDelegate> delegate;

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

Имеет смысл? Было бы хорошо установить делегата на ноль, но какой в этом смысл?

ВАШ ОТВЕТ НА ВОПРОС