Если вы установите для делегата значение 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];
}
 Brad Thomas21 окт. 2014 г., 15:19
@ geekay, почему это так?
 thesummersign10 февр. 2015 г., 11:53
это было во время бездуги
 thesummersign22 мар. 2012 г., 07:46
self.b = [[B alloc] init]; вы никогда не должны использоватьself на LHS, если вы используетеalloc на RHS, если@property дляb сохранить. просто хотел добавить.

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

Решение Вопроса

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

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

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

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

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

 Quinn Taylor02 июл. 2009 г., 08:37
+ 1 Хорошая мысль о B, возможно, об обмене сообщениями A. Это наиболее вероятно в многопоточном сценарии, но вы никогда не знаете. Это отличное приложение для слабых ссылок, если вы используете GC. Я думаю, что делегаты всегда должны быть слабыми в новом код
 marchinram20 окт. 2011 г., 06:51
Да, меня это укусило в многопоточном приложении

Ты забыл позвонить[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; - в отличие от использования (сохранить) или (копировать)

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

 Quinn Taylor02 июл. 2009 г., 01:24
+ 1 Правильно, делегатов никогда не следует оставлять. Это классическая причина сохранения циклов, поскольку делегат обычно сохраняет делегирующий объект.
 Boon02 июл. 2009 г., 02:35
Есть смысл установить для делегата значение nil, потому что, если клиент попытается вызвать объект делегата, который больше не существует, он не потерпит крах, так как для него установлено значение nil.
 Josh02 июл. 2009 г., 05:30
Вы освобождаете класс, который содержит делегат ... вы удаляете экземпляр класса из памяти в тот момент, вы получите ошибку доступа к памяти, если вы выполните какое-либо действие над объектом, очень меньше обращайтесь к своему делегату. Если я не пропустил что-то здесь ...
 Quinn Taylor02 июл. 2009 г., 08:44
Да, вы можете получить ошибку, если это произойдет, но вы можете предотвратить ее, установив значение nil. См. Ответ Питера для сценария, где это может легко произойти.

Ваш ответ на вопрос