1

我正在阅读与 ARC 相关的文章。以下是该部分:

ARC 还利用了 Objective-C 语言命名约定并推断返回对象的所有权。在 Objective-C 中,一种使用以下任一前缀进行统计的方法

  1. 分配,
  2. 复制,
  3. 可变复制
  4. 和新的

被认为正在将返回对象的所有权转移给调用者。这意味着,在您的应用程序中,当您创建一个方法时,ARC 会自动从您的方法名称中推断是返回一个自动释放的对象还是一个 +1 的保留对象。但是,有一个小警告。假设您有一个以“copy”开头的方法,如

-(NSString*) 复制权字符串;

ARC 假设它会将返回的字符串的所有权转移给调用者并自动插入一个释放。如果被调用方法和调用方法都是使用 ARC 编译的,那么一切正常。

但是,如果您的“copyRightString”方法位于未使用 ARC 编译的第三方库中,您将过度释放返回的字符串。这是因为,在调用代码上,ARC 编译器插入了一个释放来平衡由“复制”方法增加的保留计数。

相反,如果第三方库是使用 ARC 编译的,而您的方法不是,则会出现内存泄漏。

现在我有两个问题: 1.为什么“copyRightString”方法在非ARC编译的第三方库中时对象会过度释放?由于方法名称以copy开头,所以该方法不会释放对象,因为它是调用方法来释放对象的责任,因为方法的名称以复制开头,所以 ARC 将负责。

2.为什么第三方库是用ARC编译的,而我们的方法不是,为什么会有内存泄漏?由于方法名以copy开头,所以ARC不会释放它,它是调用方法释放它的责任。在我们的代码我们将发布它,因为方法名称以复制开头。

我希望我清楚!

4

1 回答 1

3

在此示例中,-copyRightString选择方法名称以显示某个问题。方法签名表明该方法返回一个包含版权信息的字符串,因此程序员会期望它返回一个自动发布的值。但意外地方法名称以 开头copy,因此 ARC 期望它返回一个保留值。方法实现可能如下所示:

- (NSString *)copyRightString
{
   return [NSString stringWithFormat:@"Copyright %d %@", 
                                     self.copyRightYear,
                                     self.companyName];
}

如果您在没有 ARC 的第三方库中编译此方法,该方法将返回一个自动释放的值。如果您现在从 ARC 代码中使用它,ARC 会看到名称以 开头copy,因此它希望此方法返回一个保留的(不是​​自动释放的)值。因此,它会过于频繁地释放返回值一次。这就是过度释放的部分。

另一方面,如果您使用 ARC 编译此方法,ARC 会看到名称以 开头copy,因此它将确保该方法返回一个保留值。然而,从非 ARC 使用此方法的程序员可能期望该方法返回一个自动释放的值(因为方法签名表明它返回一个包含版权信息的字符串)。所以他们不会在他们的代码中释放对象,从而导致内存泄漏。

于 2012-06-19T14:01:08.040 回答