iPhone dev - viewDidUnload подпредставления - PullRequest
4 голосов
/ 02 июня 2010

Мне трудно разобраться с парой методов в UIViewController, но сначала я скажу, для чего они предназначены (игнорируя построитель интерфейса, потому что я его не использую):

-init: инициализировать не относящиеся к просмотру материалы, которые не нужно освобождать в ситуациях с нехваткой памяти (т.е. не объекты или объекты, которые нельзя легко воссоздать).
-loadView: создать представление для свойства [self view].
-viewDidLoad: создать все остальные элементы вида
-viewDidUnload: разблокировать объекты, созданные в -viewDidLoad.
didReceiveMemoryWarning: ситуация с нехваткой памяти, освобождение ненужных вещей, таких как кэшированные данные, если у этого представления нет суперпредставления, [super didReceiveMemoryWarning] продолжит освобождать (выгружать) представление и вызовет -viewDidUnload.
-dealloc: отпустить все
-viewWillAppear:, -viewDidAppear:, -viewWillDisappear:, -viewDidDisappear: говорят сами за себя, не нужно, если вы не хотите отвечать (что-то делать) на эти события.

Я не уверен насчет пары вещей. Во-первых, в документации Apple говорится, что при вызове -viewDidUnload представление уже было освобождено и установлено на ноль.

  1. Будет ли -loadView вызываться снова, чтобы позже восстановить представление?
  2. Есть несколько вещей, которые я создал в -viewDidLoad, для которых я не создал ivar / свойство, потому что в этом нет необходимости, и оно будет сохранено представлением (потому что они являются его подвидом). Так что, когда представление будет выпущено, оно тоже будет выпущено, верно? Когда представление будет выпущено, оно выпустит все свои подпредставления? Потому что все объекты, которые я создал в -viewDidLoad, являются подпредставлениями [self view]. Так что, если они уже выпущены, зачем выпускать их снова в -viewDidUnload? Я могу понять данные, которые необходимы, когда представление загружается и выгружается в этих методах, но, как я и просил, зачем освобождать подпредставления, если они уже выпущены?

РЕДАКТИРОВАТЬ : После прочтения других вопросов, я думаю, что я мог бы получить его (мой второй вопрос). В ситуации, когда я просто использую локальную переменную, выделяю ее, делаю ее подпредставлением и освобождаю, он будет иметь счет сохранения 1 (от добавления его в качестве подпредставления), поэтому, когда представление освобождается, оно тоже. Теперь для элементов представления с указанием на них иваров, я не использовал свойства, потому что внешний доступ к ним не требуется. Но теперь я думаю, что это неправильно, потому что в этой ситуации:

// MyViewController.h
@interface MyViewController : UIViewController {
    UILabel *myLabel;
}

// MyViewController.m
. . .
- (void)viewDidLoad {
    myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 10)];
    [myLabel setText:@"Foobar"];
    [[self view] addSubview:myLabel];
}

- (void)viewDidUnload [
    // equivalent of [self setMyLabel:nil]; without properties
    [myLabel release];
    myLabel = nil;
}

В этой ситуации метке будет отправлено сообщение -release после того, как оно было освобождено, потому что ивар не сохранил его (потому что он не был собственностью). Но для свойства количество сохраняемых объектов будет два: представление, сохраняющее его, и свойство. Так что в -viewDidUnload оно будет освобождено. Так что лучше всего всегда использовать свойства для этих вещей, я прав? Или нет?

1 Ответ

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

Будет ли вызван -loadView снова для повторного просмотра в дальнейшем?

Да, как только кто-то получит доступ к свойству view.

Когда представление будет выпущено, оно выпустит все свои подпредставления?

Да.

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

UILabel *foo = [[UILabel alloc] init…];
[self.view addSubview:foo];
[foo release];

В этом случае метка будет освобождена, когда представление будет освобождено.


Управление памятью в вашем примере в порядке. Когда вы alloc метка, ее retainCount переходит на 1, представление сохраняет ее (retainCount = 2), затем представление освобождается и освобождает метку (rc = 1), а затем вы наконец освобождаете обозначьте себя (rc = 0, dealloc).

Чтобы сделать вещи еще более ясными - переменная myLabel не сохраняет метку явно, но вы все еще владеете ею, потому что вы ее присвоили. Это одно из основных правил управления памятью Какао: alloc +1, retain +1, release -1, autorelease -1 позже.

* +1034 * Пример: * * одна тысяча тридцать пять
@property(retain) UILabel *foo;
self.foo = [[UILabel alloc] init…];

Это будет утечка, поскольку метка получает +1 во время выделения и еще один +1 в установщике, сгенерированном для свойства foo. Прочитайте Руководство по управлению памятью Какао или учебник Скотта Стивенсона Objective-C . Управление памятью в Какао довольно простое, и, подумав, вы должны чувствовать себя совершенно комфортно в любых ситуациях.

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