Утечка взглядов и других объектов - PullRequest
2 голосов
/ 15 мая 2011

Меня всегда это смущало. Может кто-нибудь объяснить, пожалуйста, для меня?

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

Итак, я вызываю метод, чтобы получить представление и передать его непосредственно addSubView:

[scrollView addSubView:[self getView]];

А вот метод, который создает представление:

-(UIView *)getView {

   UIView *v = [[UIView alloc] init];

   // do all the guff I need to configure the view

   return v;
}

Вопрос в том, где или когда выйдет v? Должен ли я назначать его как autorelease, когда он создается в getView, или я должен разблокировать его после того, как позвонил addSubView:? Спасибо.

Ответы [ 2 ]

2 голосов
/ 15 мая 2011

Поскольку -[UIView addSubview:] получает право собственности на переданное представление, отправляя ему сообщение -retain, вы должны отправлять возвращаемое значение getView сообщения -autorelease:

return [v autorelease];
0 голосов
/ 15 мая 2011

Вывод Джейкоба верен, но его причина неверна или, по крайней мере, неясна (и я пытался, но не смог втиснуть это в комментарий).

В getSubview: вы создали объект. Теперь вы владелец *. Когда метод завершится, вы должны освободить объект, отказавшись от права собственности, иначе он будет утек. Тот факт, что вы возвращаете объект из метода, не имеет значения для этого правила.

В этом случае, поскольку вы хотите, чтобы код, вызвавший этот метод, мог что-то сделать с объектом, вы используете autorelease, говоря: «Я отказываюсь от владения, но на самом деле не избавляться от этого объекта до тех пор, пока вызывающий код не увидит, хочет ли он предъявить претензию ». То, что происходит на другом конце (сохранение, копирование, немедленное освобождение, что угодно), не имеет значения для кода в getSubview:. Все, что нужно сделать этому методу - это беспокоиться о памяти, которой он владеет. Если поступить иначе, то есть полагаться на то, что вызывающий код будет делать что-то определенное с памятью, это приведет к ошибкам.

В несколько более технических терминах объект, на который указывает v, должен быть либо освобожден, либо автоматически освобожден, поскольку v собирается выйти из области видимости в конце метода. Как только имя выходит из области видимости, вы больше не должны использовать это имя для ссылки на объект, и если это имя было единственной ссылкой, которая у вас была на объект, вы пропустили.


* Обратите внимание, что объект может иметь несколько владельцев - любой другой объект, который retain s становится частичным владельцем.

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