当使用 Clang 静态分析器分析我的 iOS Objective-C 代码时,我遇到了很多“潜在泄漏”。许多泄漏让我想知道为什么它是错误的。下面是一个让我特别疑惑的例子:
我有一个 NSDictionary
类型的类变量,用于存储一些设置。现在,当我有一种方法可以更改字典中的内容时:
- (void) loadPassengerCompartiments {
NSMutableArray *paxCompartiments = [self.outputTable objectAtIndex:2];
NSArray *paxCompSrc = [self.values objectForKey:@"PassengerCompartiments"];
for(MassPerson *passenger in paxCompSrc) {
=> [paxCompartiments addObject:[[PaxCompartimentOutputField alloc] initWithPerson:passenger]];
}
}
Clang 在 PaxCompartimentOutputField
的内联分配和直接关联上出错。
在仪器中运行此代码时,它不会泄漏。
我可以想出两种方法来解决这个问题:
- 使用
自动释放
- 用以下代码替换内联分配:
(代码)
PaxCompartimentOutputField *field = [[PaxCompartimentOutputField alloc] initWithPerson:passenger];
[paxCompartiments addObject:field];
[field release];
第一个选项是过时的恕我直言(尤其是在 iOS 上,不鼓励使用它) 第二个选项非常庞大 - 特别是在创建包含更多对象的数组时(比如 10 个加载默认设置的对象)。
我不想忽略 Clang 的警告,因为它是查找错误和漏洞的绝佳工具。对于这些情况,在 Objective-C 中执行此操作的“正确”方法是什么?
最佳答案
那是泄漏。
由于您分配初始化 PaxCompartimentOutputField
,您拥有它并且您必须放弃它的所有权。
您有 3 个选项(您已经提到了其中的 2 个):
1) 使用方便的构造函数,当可用时,或在自定义类中,声明一个。便利构造函数返回您不拥有的对象,通常是通过向它们返回的对象发送autorelease
消息。它看起来像这样:
[paxCompartiments addObject:[PaxCompartimentOutputField paxCompartimentOutputWithPerson:passenger]];
2) 使用autorelease
。
[paxCompartiments addObject:[[[PaxCompartimentOutputField alloc] initWithPerson:passenger]] autorelease];
3) 使用临时变量。
PaxCompartimentOutputField *tempField = [[PaxCompartimentOutputField alloc] initWithPerson:passenger];
[paxCompartiments addObject:tempField];
[tempField release];
关于objective-c - 当没有泄漏时,如何向 Clang 静态分析器弄清楚?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6794785/