Использование UINavigationController с экземплярами UIViewControllers того же класса и без NIB - PullRequest
1 голос
/ 25 мая 2009

Испытывая экспериментальное приложение для iPhone на основе UINavigationController, я столкнулся с проблемой, когда пользователь возвращается к предыдущему виду.

Простое приложение использует UINavigationController, в который помещаются новые экземпляры UIViewController. Все эти экземпляры принадлежат к одному и тому же классу (в этом примере класс MyViewController является подклассом UIViewController) и создаются вручную (без использования NIB). Каждый экземпляр содержит отдельный экземпляр UITableView в качестве представления UIViewController.

Следующий tableView: didSelectRowAtIndexPath: метод из класса MyViewController. Он создает и помещает другой экземпляр MyViewController в navigationController, когда пользователь выбирает ячейку таблицы:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyViewController *nextViewController = [[MyViewController alloc] initWithNibName:nil bundle:nil];
    [self.navigationController pushViewController:nextViewController animated:YES];
    [nextViewController release];
}

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

Эту ошибку можно предотвратить, не выпустив экземпляр MyViewController в tableView: didSelectRowAtIndexPath: метод выше или не вызывая dealloc для экземпляра 'myTableView' в методе dealloc MyViewController. Однако это не настоящее решение. Насколько я знаю, UINavigationController "владеет" отправленным экземпляром UIViewController, который затем можно безопасно освободить от клиента, который его выделил. Итак, что может быть не так с этим экспериментальным приложением? Почему он прекращается, когда пользователь переходит обратно?

Ниже приведены несколько других методов класса MyViewController:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        self.title = @"My Table";
        myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        myTableView.delegate = self; 
        myTableView.dataSource = self;
        self.view = myTableView;
    }
    return self;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyTable"];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithFrame:CGRectMake(0,0, 300, 50) reuseIdentifier:@"MyTable"];
        [cell autorelease];
    }
    cell.text = [NSString stringWithFormat:@"Sample: %d", indexPath.row];
    return cell;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 3; // always show three sample cells in table
}

- (void)dealloc {
    [myTableView dealloc];
    [super dealloc];
}

EDIT:

Проблема исправлена ​​- спасибо Rob Napier за указание на проблему.

Метод -loadView теперь настраивает представление с использованием локального экземпляра UITableView:

- (void)loadView {
    UITableView *myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    myTableView.delegate = self; 
    myTableView.dataSource = self;
    self.view = myTableView;
    [myTableView release];
}

1 Ответ

2 голосов
/ 25 мая 2009

Вы устанавливаете вид в неправильном методе. Вы должны установить это в -loadView, а не -initwithNibName:bundle:. Смотрите в Руководство по программированию View Controller «Использование View Controllers» для примера.

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