Испытывая экспериментальное приложение для 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];
}