是否允许使用 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]?的主要内容,如果未能解决你的问题,请参考以下文章