【问题标题】:Objective C NSCFString Leaks with NSMutableArrays带有 NSMutableArrays 的 Objective C NSCFString 泄漏
【发布时间】:2025-12-25 09:15:11
【问题描述】:

我正在清理电话簿 iPhone 应用程序中的代码,而 Instruments 中的泄漏工具报告我正在泄漏 NSCFString 对象。这是我遵循的模式:

我的应用程序中有一个 Person 类,它只有本地 NSString 成员和名字、姓氏等的关联属性。

我的视图控制器有一个 NSMutableArray 属性,该属性是在 searchBarSearchButtonClicked 事件中从 SQLite 数据库填充的。这个 NSMutableArray 填充了将用于填充我的 tableview 控件的 Person 对象。此外,如果用户单击视图中的某个人,他们的 Person 对象将被传递到 Detail 视图,以查看除姓名之外的其他信息。

当我执行第一次查找并显示结果时,没有内存泄漏。

现在,当我执行第二次查找时,理想情况下,我希望清除 NSMutableArray 并使用新结果集重新加载它,而不会泄漏内存。因此,为此,我在 personList 属性上调用 removeAllObjects,然后调用数据库重新填充 personList NSMutableArray,如下所示:

[self.personList removeAllObjects];
self.personList = [SearchService GetPersonList:searchText];
[list reloadData];

通过调用 removeAllObject 我已经摆脱了与 Person 对象相关联的泄漏。但是,我现在似乎正在泄漏从各个 Person 对象的属性中遗留下来的 NSString 对象。

这可能吗?

我是 Instruments 工具的新手,但是当我深入了解其中一个 NCSFString 泄漏时,从扩展详细信息可以看出,堆栈中的最后一行代码通常指向 @synthesize 代码行属性,例如:

@synthesize firstName;

所以,这就是为什么我认为那些 NSStrings 没有得到清理。有没有更好的方法来做到这一点,不会产生内存泄漏?

【问题讨论】:

  • 如果您可以发布 Person 类的代码,则可能更容易诊断出发生了什么。

标签: iphone objective-c xcode memory-leaks instruments


【解决方案1】:

您是否在您的 Person 类的 dealloc 方法中释放了 NSStrings?

假设您这样设置属性:

@property (retain) NSString *firstName;

当您使用 setter 设置 firstName 时,它将被保留。如果Person 实例随后被释放并解除分配,但firstName 尚未被释放,它将泄漏。

把它放在Person 类的dealloc 方法中:

- (void)dealloc
{
    [firstName release];
    [super dealloc];
}

(假设用于您的firstName 属性的相应ivar 称为firstName)。

【讨论】:

  • 这似乎有效。但是,XCode 3.2.1 cmets 中的代码分析器在我发布的 dealloc 方法中:“调用者此时不拥有对象引用计数的错误递减”。想法?
  • 代码分析器认为在-dealloc 中使用访问器方法是一个错误并警告您——关于在initdealloc 中使用访问器是否有效存在一些争论,但我认为普遍的共识是避开并直接访问 ivars(抱歉之前应该指出这一点)。
  • 这对我有用,虽然我的属性设置是:@property (nonatomic, assign) NSString* name;