我正在viewDidAppear中创建一个表视图,因为我的应用程序要求在此处创建它有多种原因。但是,当我分析我的应用程序时,我注意到内存泄漏。
我认为使用实例变量_tableView除了init和dealloc之外的任何其他方法都不是一个好主意。我应该只使用自动释放,我想确保在适当的时间释放该表。
我的表视图有一个属性。
@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];
}
答案 0 :(得分:2)
self.tableView
是retain
属性,因此合成的setter会增加保留计数。但是,当您使用UITableView
/ alloc
创建新的init
时,您还会增加保留计数。因此,此行会导致tableView
保留两次:
self.tableView = [[UITableView alloc]
initWithFrame:CGRectMake(0, 0, 320, 300)
style:UITableViewStyleGrouped];
使用alloc
/ init
时,以及使用self.tableView =
调用合成制定者时的一次。
您没有两个相应的release
来电。
处理此问题的正确方法是autorelease
设置alloc
的{{1}} / init
'UITableView对象,如下所示:
self.tableView
其余代码将按预期工作。
顺便说一句,您可能不想在self.tableView = [[[UITableView alloc]
initWithFrame:CGRectMake(0, 0, 320, 300)
style:UITableViewStyleGrouped]
autorelease];
中创建UITableView
。到那时你的观点已经出现(因此得名),你可能在那之前想要你的viewDidAppear
。每次出现视图时,您可能也不希望花费额外的费用来创建新的UITableView
。您可能希望在UITableView
中创建UITableView
,然后重复使用它,除非有充分理由不这样做。
答案 1 :(得分:1)
自动释放。你得到一个保留为alloc和另一个保留属性赋值(假设它是一个保留属性)。
你的dealloc应该处理一个而自动释放另一个。
答案 2 :(得分:0)
设置属性是好的,当你想在另一个类中使用该变量时,我设置了实例变量的属性,否则没有必要,
由于您在viewDidAppear中创建,因此它将始终在为该控制器显示视图时创建,因此最好在ViewDidDisappear方法中重新发布tableview。
如果您使用自动释放,我们将无法获得它将被释放,因此有时访问tableview将导致应用程序崩溃,
答案 3 :(得分:0)
除了其他人说的话之外,我不鼓励你在alloc
中做viewDidAppear
因为该方法可以多次调用,具体取决于其他内容(并且,除非你在另一个alloc
之前开始检查是否存在tableView,否则会导致泄漏。在viewDidLoad
中进行此操作似乎更加安全。
顺便说一句,我相信您的viewDidAppear
,viewDidDisappear
和dealloc
也应该调用他们的super
版本。