Делегаты - сохранить или назначить - освободить? - PullRequest
13 голосов
/ 25 января 2011

Я видел несколько постов, связанных с делегатами, и я хотел бы знать, как правильно на них ссылаться.Предположим, у меня есть объект, объявленный как:

@interface MyViewController : UITableViewController {
    id delegate;    
}
@property (nonatomic, retain) id delegate;
@end

В течение жизненного цикла MyViewController он будет выполнять вызовы методов своего делегата в ответ на взаимодействие с пользователем.

Когда этовремя, чтобы избавиться от экземпляра MyViewController, нужно ли delegate ivar быть release 'ed в методе реализации dealloc, поскольку он объявлен с помощью retain?

или наоборотдолжен ли delegate быть сохранен?Возможно, это должно быть @property (nonatomic, assign) id delegate?Согласно документация Apple :

сохранить ... Обычно этот атрибут используется для скалярных типов, таких как NSInteger и CGRect, или (в среде с подсчетом ссылок) для объектов, которые выне владею такими, как делегаты.

Обычно я просто следую тому, что говорят документы, но я видел много кода, который вызывает retain для делегата.Это просто "плохой код"?Я полагаюсь на экспертов здесь ... Какой правильный способ справиться с этим?

Ответы [ 3 ]

21 голосов
/ 25 января 2011

Как правило, вы хотите назначать делегатов, а не сохранять их, чтобы избежать циклического отсчета, когда объект A сохраняет объект B, а объект B сохраняет объект A. (Вы можете увидеть, что это называется «слабой ссылкой» наделегат.) Например, рассмотрим следующий общий шаблон:

-(void)someMethod {
    self.utilityObject = [[[Bar alloc] init] autorelease];
    self.utilityObject.delegate = self;
    [self.utilityObject doSomeWork];
}

, если свойства utilityObject и delegate оба объявлены с использованием retain, тогда self теперь сохраняет self.utilityObject и self.utilityObject сохраняет self.

См. Почему делегатам Objective-C обычно дается свойство присваивать вместо сохранения? для получения дополнительной информации об этом.

Если вы назначаете делегата, а не сохраняете его, тогда выне нужно беспокоиться о выпуске его в dealloc.

1 голос
/ 25 января 2011

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

0 голосов
/ 25 января 2011

Я также слышал много мнений по этому поводу. Я не знаю Правильного Пути, но я могу рассказать вам, к чему я пришел благодаря моей собственной работе.

Вы хотите retain все, что вам нужно, чтобы сохранить ручку. Это все право собственности в среде с подсчетом ссылок. Это декларация, что «мне это понадобится позже, не позволяй этому уйти».

ТАКЖЕ означает, что вы несете ответственность за отказ от претензии. Если вы специально этого не делаете, вы склонны к различным проблемам, но особенно имеете дело с делегатами, которые вполне могут сохранить объект, делегатом которого они являются. Если вы не будете иметь дело с удержанием делегата, владение будет цикличным, и объекты будут протекать. Но не забудьте освободить то, что у вас есть, и все будет в порядке.

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