为啥这个 NIB 视图在返回之前没有发布?

Posted

技术标签:

【中文标题】为啥这个 NIB 视图在返回之前没有发布?【英文标题】:Why is this NIB view not released before being returned?为什么这个 NIB 视图在返回之前没有发布? 【发布时间】:2010-07-31 14:04:36 【问题描述】:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellId];
if (cell == nil) 
    
    [[NSBundle mainBundle] loadNibNamed:@"ThemeCell" owner:self options:nil];
        cell = self.themeCell;
        self.themeCell = nil;

...
return cell;

我的理解是self.themeCell = nil; 应该销毁该对象,因为它不再有任何所有者。 cell = self.themeCell 不保留它,而只是分配它。那么是什么让细胞保持活力呢?我只能假设合成属性是自动释放旧值而不是立即释放它。是这样吗?

【问题讨论】:

【参考方案1】:

nib 加载过程稍微(但不是很)复杂,并且在 OSX 和 iPhone 平台之间有所不同。您可以在资源编程指南的the Nib Object Life Cycle 部分阅读有关此内容的信息。在表 1-1 中,您会发现:

创建 nib 文件中的对象 保留计数为 1,然后 自动发布。当它重建 对象层次结构,然而,UIKit 重新建立之间的连接 使用 setValue:forKey 的对象: 方法,它使用可用的 setter 方法或通过以下方式保留对象 如果没有 setter 方法,则默认为 可用

所以发生的情况是,创建单元格时保留计数为 1,然后当使用合成设置器设置它时,它增加到 2。当您将属性设置为 nil 时,保留计数下降为 1,单元格返回到表格视图。表视图将其添加到其视图层次结构中,从而保留它(并且可能在其逻辑的其他部分也保留它)。毕竟,autorelease 池已耗尽。

我只能假设 syntesized 属性自动释放旧的 价值而不是释放,这是 案例?

不,合成的 setter 会立即释放对象。 (尽管某些框架类可能会保留对象更长时间,例如,如果它是一个需要动画的视图。)

【讨论】:

【参考方案2】:

AFAIK,综合属性使用release,而不是autorelease

可能是单元格有一个委托或在 NIB 中指定的保留所有权的委托,或者 loadNibNamed:owner:options: 调用中的某些内容在仍待处理的对象上设置了自动释放。在self.themeCell=nil; 前后加上NSLog(@"Retain Count: %d", [cell retainCount]); 进行验证。

【讨论】:

以上是关于为啥这个 NIB 视图在返回之前没有发布?的主要内容,如果未能解决你的问题,请参考以下文章

在这个项目中,为啥我无法访问从 nib 加载的视图属性?

可插拔自定义视图 Nibs (Nib-in-a-Nib):内存泄漏 - 为啥?

为啥 iOS 不自动旋转从 Nib 加载的视图在被 didReceiveMemoryWarning 释放后?

无法在 Bundle 中为自定义表格视图单元格类加载 NIB

为啥基于类的视图返回类型对象'Profile'没有属性'model'?

Nib 文件在加载时忽略状态栏。为啥?