【发布时间】:2011-09-28 11:09:34
【问题描述】:
我有一个模式视图,它是一个导航控制器。当其 UITableView 中的一行被点击时,该行的正确视图控制器应该被初始化并推送到导航控制器的堆栈上(以便屏幕现在显示该视图控制器)。但它不起作用。我一直在尝试调试它一段时间,在调用 pushViewController 时,导航控制器的保留计数似乎为 0。我认为这意味着它已被释放,这是问题的根源。但我不知道为什么。
在以下代码中,AddSportDelegate.m 显示了包含必要导航控制器(_addItemNavController) 的模式视图,该导航控制器使用必要的AddItemTableViewController 进行了初始化。点击由AddItemViewController 管理的表视图的其中一行会调用AddSportDelegate 的showAddItemDataView: 方法,这反过来应该将正确的ViewController 推入_addItemNavController 堆栈。但是,正如我在代码中的注释中指出的那样,此时 _addItemNavController 的保留计数为 0。
注意:我意识到这段代码有内存泄漏。为了简洁起见,我删除了一些发布行。我也没有包含应该被推送的视图控制器的代码,因为它目前除了UILabel 识别它是正确的视图控制器之外没有任何东西。
AddItemDelegate.m
@synthesize addItemNavController = _addItemNavController;
- (void)showAddItemViewController:(UIViewController *)viewController
{
_parentVC = viewController;
[_parentVC retain];
tc = [[AddItemTableViewController alloc] init];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithTitle:@"Cancel" style:UIBarButtonSystemItemDone target:self action:@selector(cancelAdd)];
tc.navigationItem.leftBarButtonItem = cancelButton;
tc.title = @"Select a Category";
_addItemNavController = [[AddItemNavController alloc] initWithRootViewController:tc];
tc.superViewController = _addItemNavController;
[_parentVC.navigationController presentModalViewController:_addItemNavController animated:YES];
}
- (void)showAddItemDataView:(SportCategory *)category
{
[category retain];
UIViewController *vc;
if (category.name == @"Soccer") {
vc = [[AddSoccerDataViewController alloc] init];
}else{
vc = [[AddBaseballDataViewController alloc] init];
}
//retain count already 0
NSLog(@"retain count: %i", [_addItemNavController retainCount]);
[_addItemNavController.navigationController pushViewController:vc animated:YES];
}
AddItemTableViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
_addItemDelegate = [[AddItemDelegate alloc] init];
SportCategory *soccer = [[SportCategory alloc] initWithCategoryName:@"Soccer"];
SportCategory *baseball = [[SportCategory alloc] initWithCategoryName:@"Baseball"];
_categories = [[NSArray alloc] initWithObjects:soccer,baseball,nil];
[self.tableView reloadData];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SportCategory *selectedCategory = [_categories objectAtIndex:[indexPath row]];
[_addItemDelegate showAddItemDataView:selectedCategory];
}
【问题讨论】:
-
你在哪里调用 showAddItemViewController?看起来 _addItemNavController 甚至没有分配,如果调用了 showAddItemViewController 然后检查 tc.superViewController 如果你在某个地方调用释放它,如果 tc.superViewController 是变量或分配属性,那么它可以释放 _addItemNavController。
标签: iphone ios ipad memory-management uinavigationcontroller