是否允许使用 ARC 在 ObjC 中调用 [obj copy]?

Posted

技术标签:

【中文标题】是否允许使用 ARC 在 ObjC 中调用 [obj copy]?【英文标题】:is it allowed to call [obj copy] in ObjC with ARC? 【发布时间】:2012-11-03 22:29:33 【问题描述】:

关于 ARC,我不明白一件事:我们现在应该如何处理使用 [... copy] 创建的局部变量?如果我使用(copy) 标志创建属性,ARC 会自动处理此问题,但据我所知,变量没有__copy 标志。

我已经用这样的代码对此进行了测试:

@interface Foo : NSString
@end

@implementation Foo

- (void) dealloc 
  NSLog(@"%p deallocated", self);


- (NSUInteger) length 
  return 1;


- (unichar) characterAtIndex: (NSUInteger) i 
  return 'x';


@end

- (void) foo 
  Foo *f = [[Foo alloc] init];
  NSLog(@"%p", f);

  Foo *f2 = [f copy];
  NSLog(@"%p", f2);

我得到的是:

0x102406530
0x102015f10
0x102406530 deallocated

我从来没有得到“0x102015f10 deallocated”,这表明复制的变量没有被释放。它甚至没有自动释放,因为当我创建另一个返回自动释放对象的方法[Foo foo] 时,我确实在片刻之后收到了“已释放”消息。

那么有什么方法可以在不将其转换为属性的情况下释放它?

【问题讨论】:

如果你打算做这个实验,那么你最好使用一个你完全理解内存管理的类。 NSString 有谁知道什么内存优化,所以它不会给你一个很好的基础来玩。另外NSString 是类集群的一部分,继承并不像你做的那么简单,你需要跳过更多的圈子。 @Paul.s 所以你是英国人,对吧?我不知道存在“你是”。这是什么构造? 【参考方案1】:

好吧,我的错 - ARC 实际上确实正确处理了复制的对象。由于使用 NSString 进行测试,我得到了错误的结果,因为我想使用一个已经实现复制而不是显式实现它的类;当我对继承自 NSObject 的类重复测试并通过返回 [[Foo alloc] init] 实现 copyWithZone: 时,我收到了两条“已释放”消息。感谢@Paul.s 指出这一点。

【讨论】:

我猜在 ARC 下,copy 返回一个引用计数为 1 的对象,然后当您将它分配给强引用时,它不会再次保留,如果编译器注意到该对象是通过复制另一个创建。 实际上,ARC 确实可以正确处理复制的对象。而且你可以继承 NSString,但是文档说明你必须重写一些方法,其中包括 NSCopying 的实现

以上是关于是否允许使用 ARC 在 ObjC 中调用 [obj copy]?的主要内容,如果未能解决你的问题,请参考以下文章

Unity中的ARC ObjC代码?

合适的 -Is -fno-objc-arc 支持

尽管标记了文件 -fno-objc-arc,但 ARC 禁止在结构或联合中使用 Objective-C 对象

前面有@objc 的函数和没有@objc 的函数之间的区别

Xcode5 中无法设置 -fno-objc-arc

在启用弧的应用程序中重构#ifndef __OBJC_GC_