Управление памятью с делегатами? - PullRequest
4 голосов
/ 22 июня 2010

Управление памятью с делегатами, насколько я понимаю, я не сохраняю делегатов, я немного не уверен, что делать с делегатом, если представление выгружается (через viewDidUnload) и позже воссоздается (через viewDidLoad)?

@property(assign) SomeClass *someDelegate;

.

- (void)viewDidLoad {
    [super viewDidLoad];
    someDelegate = [[SomeClass alloc] init];
    [someDelegate setDelegate:self];
}

-(void)viewDidUnload {
    [super viewDidUnload];
    [self setSomeDelegate:nil];
}

-(void)dealloc {
[super dealloc];
}

PS: Возможно, я не на том пути, я просто пытаюсь разобраться в этом ...

ура Гари

Ответы [ 2 ]

2 голосов
/ 22 июня 2010

Если вы используете assign для своего свойства, вы не вызываете retain для объекта.

Это означает, что вы определенно НЕ должны вызывать release или autorelease на нем!

Твоя линия в твоей сделке

[someDelegate release];

вызовет сбой в будущем - вы должны удалить его. Вам не нужно заботиться о назначенных свойствах в методе dealloc.

Ваша линия

[self setSomeDelegate:nil];

не протечет.


Однако у вас, похоже, есть [[someDelegate alloc] init] в вашем viewDidLoad методе. Это необычно; для делегата нормально быть внешним объектом, а не созданным вами. В вашем случае это на самом деле не делегат, это просто объект, который делает что-то для вас - вы должны переименовать его и изменить свойство на сохранение (и не забудьте освободить его в dealloc).

В настоящее время, если ваше свойство установлено на (назначить), а кто-то другой устанавливает его, вы утечете свой первоначальный делегат. Если вы используете только делегат внутри этого класса, возможно, он вообще не должен быть свойством? Если вы просто хотите читать его за пределами своего класса, вы можете использовать (только для чтения) вместо assign (и изменить [self setSomeDelegate:nil] на someDelegate=nil;)

Ваша строка в viewDidUnload, в которой для делегата установлено значение nil, устраняет проблему, поднятую во втором комментарии: вы удаляете делегата, поэтому к тому времени, когда вы снова наберете viewDidLoad, ваш делегат уже равен нулю :)

1 голос
/ 22 июня 2010

Это может пролить свет на понимание, почему

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

A создает B A устанавливает себя в качестве делегата B ... A освобождается его владельцем

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

Вам не стоит беспокоиться об уходе А, потому что он владеет Б и, таким образом, получает избавиться от него в dealloc.

...