2

当使用 Clang 静态分析器分析我的 iOS 目标 C 代码时,我得到了很多“潜在的泄漏”。许多泄漏让我想知道为什么它是错误的。让我特别想知道的一个例子如下:

我有一个 type 的类变量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. 在仪器中运行此代码时,它不会泄漏。

我可以想出两种方法来解决这个问题:

  1. 利用autorelease
  2. 用以下代码替换内联分配:

(代码)

PaxCompartimentOutputField *field = [[PaxCompartimentOutputField alloc] initWithPerson:passenger];
[paxCompartiments addObject:field];
[field release];

第一个选项是过时的恕我直言(尤其是在 iOS 上不鼓励使用它)第二个选项非常庞大 - 特别是在创建包含更多对象的数组时(比如 10 个加载默认设置的对象)。

我不想忽略 Clang 的警告,因为它是查找错误和泄漏的绝佳工具。对于这些情况,在 Objective-C 中执行此操作的“正确”方法是什么?

4

2 回答 2

8

那是泄漏。

因为你 alloc-init 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];
于 2011-07-22T19:11:48.870 回答
2

有一个可以与 Clang 一起使用的源注释列表。

这些可能会有所帮助。

于 2011-07-22T19:03:32.067 回答