Iphone 韩元';t重新分配UITableViewController';s的tableView属性是否导致泄漏?

Iphone 韩元';t重新分配UITableViewController';s的tableView属性是否导致泄漏?,iphone,Iphone,我创建了UITableView的一个子类,并希望将其与UITableView控制器一起使用,以获得键盘出现时自动滚动的好处。在视图控制器的loadView(源自UITableViewController)中,我执行了以下操作: - (void)loadView { [super loadView]; self.tableView = [[MyCustomTableView alloc] initWithFrame:[UIScreen mainScreen].application

我创建了UITableView的一个子类,并希望将其与UITableView控制器一起使用,以获得键盘出现时自动滚动的好处。在视图控制器的loadView(源自UITableViewController)中,我执行了以下操作:

- (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引用的任何内容发生泄漏吗?”。很好。