свойство «назначить» и «сохранить» для делегата - PullRequest
16 голосов
/ 03 марта 2011

Для разработчиков iOS делегаты используются практически везде.

И кажется, что для делегата, подобного этому, нам нужно использовать "назначить" вместо сохранения

@property(assign) id delegate;

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

Я видел много кода, и они все еще использовали «сохранить».Так что вопрос здесь в том, будем ли мы по-прежнему сталкиваться с проблемой циклического цикла, если мы будем использовать retain для делегата?

Спасибо

1 Ответ

26 голосов
/ 03 марта 2011

Документация гласит:

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

В качестве примера давайте рассмотрим UITableViewController, который реализует протокол UITableViewDelegate. UITableView сохраняется его контроллером представления, хотя UITableView не сохраняет своего делегата.

Как сказано в документе выше, UITableViewController завершит свое освобождение только тогда, когда будут освобождены все его сильные ссылки. Поскольку UITableView с UItableViewController в качестве делегата не сохраняет его, когда владелец UItableViewController вызывает для него функцию release, счетчик сохранения сбрасывается в ноль и вызывается метод dealloc.

Теперь представьте, что UITableView сохраняет свой делегат. UITableViewController будет иметь счет удержания по крайней мере +2. Один с его владельцем, а другой с UITableView. Когда владелец UITableViewController вызывает release для него, счетчик сохранения будет равен +1, а не нулю, как ожидалось, и поэтому метод dealloc не будет вызываться, пока счет сохранения не достигнет нуля. Чтобы достичь нуля, UITableViewController должен выпустить свой UITableView, который затем освободит его делегат (UITableViewController). Поскольку UITableViewController удаляет свое представление (UITableView) только тогда, когда освобождение этого момента никогда не произойдет, потому что количество сохранений не будет ниже + 1.

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

Имеет ли это смысл?

...