如何修复 _NSCFNumber 的 iOS 内存泄漏?

Posted

技术标签:

【中文标题】如何修复 _NSCFNumber 的 iOS 内存泄漏?【英文标题】:How to fix iOS memory leak from _NSCFNumber? 【发布时间】:2015-07-09 14:30:48 【问题描述】:

这是我重新加载 _collectionView 特定部分的代码。当我在 Xcode 6.3 Instruments 中使用 Leaks 模板检查内存泄漏时,它显示在线泄漏

[_collectionView reloadSections:indexToLoad];

和 _NSCFNumber 作为泄漏对象。 这是我的代码:

NSMutableIndexSet* indexToLoad = [NSMutableIndexSet new];
for (NSInteger index in array) 
    if (index != NSNotFound) 
        [indexToLoad addIndex:index];
    

if (indexToLoad.count > 0) 
    [_collectionView reloadSections:indexToLoad];

当我在某处读到时,“泄漏工具会向您显示分配泄漏的位置,但不会显示导致泄漏的代码行”,我怎样才能找到泄漏的原因?还有如何解决这个泄漏?

注意:运行此代码的类启用了 ARC(整个项目都启用了 ARC)。此代码也在主线程上运行。

提前感谢您的回答:)

【问题讨论】:

没有发生泄漏的行。当对该对象的所有引用都超出范围但没有人费心收集该对象时,就会发生泄漏。在你的情况下,你的代码甚至没有编译开始,所以你能告诉我们你遇到问题的实际代码吗? 真的,向我们展示实际运行的代码。如果该代码编译,那么你真的需要打开一些编译器警告。 【参考方案1】:

我注意到您正在迭代一个数组并将其内容封装为NSInteger。由于您不能将 NSInteger 添加到 Objective-C 数组中,我将假设这是一个 NSNumber 的数组,恰好是正在泄漏的类。

当您将对象(例如 NSNumber)添加到集合(例如 NSArrayNSSet 等)时,集合会创建对该对象的 STRONG 引用。这意味着当NSNumber 超出ARC 范围或垃圾收集器不会出现并释放它时。然而,这可能会导致一些问题,例如retain cycles。

怀疑正在发生的事情(如果没有实际测试您的完整代码,我无法确定)是当 NSMutableIndexSet 超出范围时,ARC 会出现并尝试释放所有 @ 987654330@ 它包含但发现它不能的对象,因为它们仍然由数组保留。如果不是,那么在代码中的某个地方,您将挂在一个或多个 NSNumber 实例上,而 ARC 不喜欢它。

解决方案: 在内存管理方面,ARC 并不是灵丹妙药。它使内存管理更加友好,因此人们倾向于假设他们可以编写他们喜欢的任何代码,而 ARC 将负责其余的工作。您仍然需要了解您的参考资料(strongweak)以及何时使用每个参考资料。还要确保你知道默认状态是什么;例如@property NSNumber *num; 相当于@property (nonatomic, strong) NSNumber *num;

【讨论】:

以上是关于如何修复 _NSCFNumber 的 iOS 内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

iOS报错[__NSCFNumber length]: unrecognized

iOS:寻找 NSDictionary 值时出现错误:[__NSCFNumber isEqualToString:]: unrecognized selector sent to instanc

ios [__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0x7a97d4c0'报错

无法将“__NSCFNumber”()类型的值快速转换为“NSArray”

无法在 Swift 2 中将“__NSCFNumber”类型的值转换为“NSString”

[__NSCFNumber 长度]:无法识别的选择器发送到实例 0xb000000000000113'