Iphone 韩元';t重新分配UITableViewController';s的tableView属性是否导致泄漏?
我创建了UITableView的一个子类,并希望将其与UITableView控制器一起使用,以获得键盘出现时自动滚动的好处。在视图控制器的loadView(源自UITableViewController)中,我执行了以下操作:Iphone 韩元';t重新分配UITableViewController';s的tableView属性是否导致泄漏?,iphone,Iphone,我创建了UITableView的一个子类,并希望将其与UITableView控制器一起使用,以获得键盘出现时自动滚动的好处。在视图控制器的loadView(源自UITableViewController)中,我执行了以下操作: - (void)loadView { [super loadView]; self.tableView = [[MyCustomTableView alloc] initWithFrame:[UIScreen mainScreen].application
- (void)loadView
{
[super loadView];
self.tableView = [[MyCustomTableView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame style:UITableViewStyleGrouped];
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
这不应该导致重新分配之前引用的任何self.tableView
都发生泄漏吗?我运行了构建和分析,但它没有将其报告为泄漏
然而,如果我想“做个好人”
…显示“我的视图”时会发生各种严重的崩溃。有谁能向我解释一下简单的重新分配是否会导致泄漏,如果是,如何正确地做到这一点
提前感谢。否,它不会导致泄漏,因为setter方法
setTableView:
(在为属性指定新值时调用)将自动释放旧值。这就是属性的用途。不,它不会导致泄漏,因为setter方法setTableView:
(在为属性指定新值时调用)将自动释放旧值。这就是属性的用途。正如Ole Begemann所说,当您使用点符号赋值时,不仅仅是简单赋值。由于setTableView:
是一个“保留属性”,它看起来像这样:
- (void)setTableView:(UITableView *)newTable
{
if(newTable != tableView) {
[tableView release];
tableView = [newTable retain];
}
}
因此,你的“做个好人”方法的问题如下。
如果您只是在tableview对象上调用release
,那么您没有使用属性设置器,也就是说,您没有将tableview设置为nil
。调用self.tableView=[[MyCustomTableView alloc]init…
时,当前tableView指向一个非零的、已释放的内存块。此内存块setTableView:
将再次尝试释放,并发出EXC\u BAD\u指令
当您对某个对象调用
release
时,如果该对象的指针将来可能会被重用,请务必在之后将其设置为nil
。这样,您就可以将指针标记为已解除分配,而不会有过度释放的风险。或者只使用retain属性,当您将其分配给nil
时,它将为您执行release
正如Ole Begemann所说,当您使用点表示法进行赋值时,不仅仅是简单的赋值。因为setTableView:
是一个“保留属性”,它看起来像这样:
- (void)setTableView:(UITableView *)newTable
{
if(newTable != tableView) {
[tableView release];
tableView = [newTable retain];
}
}
因此,你的“做个好人”方法的问题如下。
如果您只是在tableview对象上调用release
,那么您没有使用属性setter,这意味着您没有将tableview设置为nil
init…当前tableView指向一个非零的、已释放的内存块。setTableView:
将再次尝试释放该内存块,并发出EXC\u BAD\u指令
当您对某个对象调用
release
时,如果该对象的指针将来可能会被重用,请务必在之后将其设置为nil
。这样,您就可以将指针标记为已解除分配,而不会有过度释放的风险。或者只使用retain属性,当您将其分配给nil
时,它将为您执行release
实际上,您的示例将导致泄漏
self.tableView = [[MyCustomTableView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame style:UITableViewStyleGrouped];
设置self.tableView将使retain增加1,alloc将使retain增加1
当您稍后将self.tableView设置为另一个值时,retain count将减少1,剩下1,因此您分配的MyCustomTableView将永远不会被释放
loadView
崩溃的原因是,在您分配和添加自己的视图之前,存在的初始表视图已正确设置,带有1个retain。因此,当您释放它时,系统也会尝试释放它,但到那时它已被解除分配,并且随后会出现问题
正确的方法是(自动)释放分配的MyCustomTableView
:
self.tableView = [[[MyCustomTableView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame style:UITableViewStyleGrouped] autorelease];
这样,它将只有1个retain count(保留计数),当您(重新)设置
self.tableView
时,它将降至零。实际上,您的示例将导致泄漏
self.tableView = [[MyCustomTableView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame style:UITableViewStyleGrouped];
设置self.tableView将使retain增加1,alloc将使retain增加1
当您稍后将self.tableView设置为另一个值时,retain count将减少1,剩下1,因此您分配的MyCustomTableView将永远不会被释放
loadView
崩溃的原因是,在您分配和添加自己的视图之前,存在的初始表视图已正确设置,带有1个retain。因此,当您释放它时,系统也会尝试释放它,但到那时它已被解除分配,并且随后会出现问题
正确的方法是(自动)释放分配的MyCustomTableView
:
self.tableView = [[[MyCustomTableView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame style:UITableViewStyleGrouped] autorelease];
这样,它将只有1个retain count,当您(重新)时,它将降至零设置
self.tableView
有点晚,但我很困惑。上面的例子中有双重保留,因此会有漏洞,不是吗?你是对的,Kalle,OP的代码有漏洞。我实际上没有看作业,只是回答OP的问题,“这不应该导致在重新分配之前引用的self.tableView发生泄漏吗?“.接得好。有点晚了,但我很困惑。上面的例子中有双重保留,因此会有漏洞,不是吗?你是对的,Kalle,OP的代码有漏洞。我实际上没有看作业,只是回答OP的问题,“这难道不应该导致在重新分配之前self.tableView引用的任何内容发生泄漏吗?”。很好。