Создание табличного представления в ViewDidAppear - PullRequest
0 голосов
/ 01 апреля 2012

Я создаю табличное представление в viewDidAppear, потому что мое приложение требует его создания здесь по нескольким причинам. Однако я замечаю, что у меня возникает утечка памяти при анализе приложения.

Я думал, что использование переменной экземпляра _tableView не очень хорошая идея в любом другом методе, кроме init и dealloc. Если я просто использую autorelease, я хочу убедиться, что таблица будет освобождена в соответствующее время.

Есть свойство для моего просмотра таблицы.

@property (nonatomic, retain) UITableView *tableView;

И я создаю табличное представление так:

- (void)viewDidAppear:(BOOL)animated
{
    self.tableView = [[UITableView alloc]
                      initWithFrame:CGRectMake(0, 0, 320, 300) 
                      style:UITableViewStyleGrouped];

    // Table View properties
    self.tableView.dataSource = self;
    self.tableView.delegate = self;

    [self.view addSubview:self.tableView];
}

- (void)viewDidDisappear:(BOOL)animated
{
    self.tableView = nil;
}

- (void)dealloc
{
    [_tableView release];
}

Ответы [ 4 ]

2 голосов
/ 01 апреля 2012

self.tableView является свойством retain, поэтому ваш синтезированный сеттер увеличивает количество сохраняемых данных.Но когда вы создаете новый UITableView, используя alloc / init, вы также увеличиваете количество сохраняемых данных.Таким образом, эта строка приводит к тому, что tableView сохраняется дважды:

self.tableView = [[UITableView alloc]
                  initWithFrame:CGRectMake(0, 0, 320, 300) 
                  style:UITableViewStyleGrouped];

Один раз, когда вы используете alloc / init, и один раз, когда вы вызываете синтезированный сеттер, используя self.tableView =.

У вас нет двух соответствующих release вызовов.

Надлежащим способом обработки этого будет autorelease alloc / init d для объекта UITableView, для которого для self.tableView установлено значениеПримерно так:

self.tableView = [[[UITableView alloc]
                   initWithFrame:CGRectMake(0, 0, 320, 300) 
                   style:UITableViewStyleGrouped]
                  autorelease];

Остальная часть вашего кода будет работать, как и ожидалось.

Кроме того, вы, вероятно, не хотите создавать UITableView в viewDidAppear.К тому времени ваше мнение уже появилось (отсюда и название), и вы, вероятно, захотели свой UITableView до этого.Вы также, вероятно, не хотите, чтобы ЦП затрачивал на создание нового UITableView каждый раз, когда появляется представление.Возможно, вы захотите создать UITableView в viewDidLoad и затем использовать его повторно, если только для этого нет веской причины.

1 голос
/ 01 апреля 2012

Autorelease.Вы получаете одно удержание для alloc, а другое - для присвоения свойства (при условии, что это сохраняемое свойство).

Ваш dealloc должен обрабатывать одно, а второй - автоматический выпуск.

0 голосов
/ 01 апреля 2012

В дополнение к тому, что сказали другие ребята, я бы отговорил вас делать alloc в viewDidAppear, потому что этот метод может вызываться несколько раз в зависимости от того, что еще происходит (и, кстати, вызывать утечки). если только вы не начнете проверять существование tableView до alloc 'другого). Делать это в viewDidLoad кажется гораздо безопаснее.

Кроме того, я считаю, что ваши viewDidAppear, viewDidDisappear и dealloc также должны вызывать свои super версии.

0 голосов
/ 01 апреля 2012

Установка свойства хорошая, я устанавливаю свойство для переменной экземпляра, когда вы хотите использовать эту переменную в другом классе, в противном случае это не нужно,

Поскольку вы создаете в viewDidAppear, оно будет создаваться всегда, когдадля этого контроллера отображается представление, поэтому лучше выпустить представление таблицы в методе ViewDidDisappear.

Если вы используете autorelease, мы не получим, когда он будет выпущен, поэтому в некоторых случаях доступ к tableview вызовет сбой приложения,

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