Вопрос об управлении памятью iPhone (добавление подпредставления к представлению в операторе for) - PullRequest
1 голос
/ 22 марта 2009

Мне нужно добавить больше представлений в представление для обработки нескольких веб-адресов и щелчков на ярлыках. Я пытаюсь сделать это в заявлении. Мой код примерно такой:

// we have a UITabbarViewController for holding amongs other the parentViewController
UITabBarController *tabbedViewController = [[UITabBarController alloc] init];

// create the parentViewController
ParentViewController *parentViewController = [[ParentViewController alloc] initWithNibName:@"parentViewController" bundle:nil];
[parentViewController.view setNeedsDisplay];

// add parentViewController into tabbedViewController
tabbedPlayerViewController.viewControllers = [NSArray arrayWithObjects: ... parentViewController, nil];

// All the things are inside a UINavigationController
// push the view
[self.navigationController pushViewController:tabbedViewController animated:YES];

// setting up  the views individually...
// not listed here



for (NSDictionary *url in urls) {

        // init my controller with a nib file 
        UIViewController *webadressViewController = [[WebadressViewController alloc] initWithNibName:@"WebadressViewController" bundle:nil]; 

        // position the view ...
        // ... not listed here

        // add webaddress to parent view
        [parentViewController.view addSubview: webaddressViewController.view];

}

[parentViewController release];
[tabbedViewController release];

Я думаю, что у меня могут быть некоторые проблемы с управлением памятью, потому что webaddressViewController имеет 1 как счетчик сохранения, поэтому он должен быть освобожден где-то в моем коде. Но если я отпущу его в блоке for, все подпредставления исчезнут.

Мой вопрос: как я могу выпустить эти объекты?

(как я вижу проблема в следующем: когда я вызываю addSubview для parentViewController, ему будет принадлежать webaddressViewController.view, но не сам webaddressController. Поэтому, если я отпущу webaddressViewController, его вид тоже исчезнет.)

Ответы [ 4 ]

4 голосов
/ 24 марта 2009

Вы создаете webAdressViewController для каждого URL, но вы не держите эти контроллеры представления, чтобы впоследствии их можно было освободить. Если вы хотите закодировать его таким образом, вам также нужно сохранить массив webAdressViewControllers как свойство в любом объекте, к которому принадлежит этот код, - и затем освободить их в своем методе dealloc.

Но мне интересно, почему вы вообще создаете контроллеры webAdressViewControllers? Есть ли у вас код в классе webAdressViewController, кроме того, который создает представление? (Если вы говорите об освобождении контроллеров на этом этапе, я подозреваю, что нет.) Если вам позже не нужны контроллеры, почему бы не создать представления непосредственно на этом этапе, а затем добавить их как подпредставления и освободить их? Это избавит вас от необходимости держать вокруг себя контроллеры представления, которые вам не нужны.

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

parentViewController имеет счетчик сохранения два - один раз для alloc init и два раза для добавления в массив. Если вам не нужно снова напрямую обращаться к этому контроллеру (т. Е. Если контроллер с вкладками выполняет все необходимые функции управления просмотром), то вы должны отменить его один раз.

0 голосов
/ 24 марта 2009

Хотя это, вероятно, не связано с рассматриваемой проблемой, обратите внимание, что UINavigationController не поддерживает добавление UITabBarController. См. этот ТАК вопрос (и ответы).

0 голосов
/ 23 марта 2009

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

UIViewController *webadressViewController = [[[WebadressViewController alloc] initWithNibName:@"WebadressViewController" bundle:nil] autorelease];

Или добавьте оператор release в строку LAST цикла (рекомендуется):

[webaddressViewController release];

Если у вас плотный цикл, как у вас здесь выглядит, он будет более эффективным, если вы будете использовать традиционный шаблон размещения / выпуска.

Если вы оставите код как есть, у вас будет утечка памяти.

0 голосов
/ 23 марта 2009

Вы должны освободить каждое представление внутри цикла сразу после отправки сообщения addSubView. parentViewController.view сохранит представления и освободит их как часть своего dealloc.

Если вы отпустите их до этого, представление будет освобождено.

Вы, наоборот, должны держать своего parentViewController. Это контроллер представления, которому принадлежит созданное вами представление. Когда вы отпускаете его, он освобождает представление, к которому вы добавили все остальные представления, - освобождая их по очереди.

Вы отпускаете контроллер parentView, когда пользователь отклоняет его.

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