使用ARC时需要遵循的规则
博客专区 > lightUp 的博客 > 博客详情
使用ARC时需要遵循的规则
lightUp 发表于3年前
使用ARC时需要遵循的规则
  • 发表于 3年前
  • 阅读 12
  • 收藏 0
  • 点赞 0
  • 评论 0

【腾讯云】如何购买服务器最划算?>>>   


如果想用ARC,必须服从一些新规则

1. 对象的Alloc/Init

创建对象的方法跟以前一样,但你一定不能调用retain/release/autorelease/retainCount。也不能通过selector偷偷地调用它们: 禁止使用@selector(retain)和@selector(release)。

2. dealloc方法

ARC为自动为你调用,一定不能直接调用dealloc。不过,如果你需要释放实例变量以外的资源,还是可以创建自定义的dealloc方法。但在这个方法里,不要调用[super dealloc]。因为ARC会帮你调。

3. 声明的属性

在ARC之前,我们是用@property指令中的assign/retain/copy参数来告诉编译器,如何管理这些属性的内存。用了ARC之后,这些参数就作废了,改用weak/strong这两个参数。

4. C结构中的对象指针

同样禁止使用。文档里建议不要把它们放在结构了,改放到类里去。否则ARC就不认识它们了。可能会出现一些移植上的问题。不过,ARC是可以以文件为单位来关闭的。参考下文的“引入不兼容ARC的代码”。

5. id与void*之间的临时互转

当我们在Core Foundation的C函数和Foundation Kit的Objective-C方法间传递对象时,常常需要进行id和void*两个类型的互转。叫做免费桥接(Toll Free Bridging)。

如果使用ARC,必须在CF对象进入和脱离ARC的控制时,用提示/限定符来告知编译器。限定符有__bridge、__bridge_retain和__bridge_transfer。另外,仍需要用CFRetain和CFRelease来管理Core Foundation的对象。

这一块已经比较高深了,如果你不清楚CF对象是什么,也不需要太烦恼。


6. 以@autoreleasepool代替NSAutoReleasePool

兼容ARC的代码不能再使用NSAutoReleasePool对象,而要改用@autoreleasepool{ }块。

7. 其它

基于Zone的内存已经没了(在运行时里也没了)。不能再使用NSAllocateObject和NSDeallocateObject。


ARC限定符 - 声明的属性

身为程序员,习惯于做出一些决定,例如把某个量声明为变量还是常量、本地还是全局,等等。因此,在这里,我们也要决定某个属性与其它属性的关系。我们用strong/weak来把这一关系告诉编译器。

强引用

强引用是对某对象的引用,并且能阻止它被回收。换句话说,强引用创建了一个所有关系。在ARC之前,我们这么写:

// Non-ARC Compliant Declaration
@property(retain) NSObject *obj;

在ARC下,我们需要这么写,以确保当前实例获得被引用对象的所有权(主人不被回收,它也不能被回收)。

// ARC Compliant Declaration
@property(strong) NSObject *obj;

弱引用

弱引用是对某对象的引用,但不能阻止它被回收。换句话说,弱引用并不会创建所有关系。在ARC之前,我们这么写:

// Non-ARC Compliant Declaration
@property(assign) NSObject *parentObj;

在ARC下,我们需要这么写,以确保当前实例没有获得被引用对象的所有权(一般来说,子对象不应该拥有父对象,这时可以用弱引用)。

// ARC Compliant Declaration
@property(weak) NSObject *parentObj;


ARC限定符 - 常规变量

上一节是说明如何管理属性。对于常规变量,则有:

__strong
__weak
__unsafe
_unretained
__autoreleasing

一般来说,我们不太需要使用上面这些限定符。在使用移植工具的时候可能会看到那么几个,但新工程基本上不需要。

__strong: 默认限定符,不需要显式指定。表示任何用alloc/init创建的对象在当前范围的生命期内得以保留。“当前范围”是指变量声明语句所在的两个大括号之间(方法、循环、块,等等)。

__weak: 表示对象可以随时被摧毁。只有当它被其它对象强引用时才有用。__weak变量在摧毁时,被设为nil。

__unsafe_unretained: 与__weak类似,但在摧毁时,不设为nil,保留原值(不再指向有效的东西)。

__autoreleasing: 不要与autorelease搞混,它用于通过引用传递对象,比如,通过引用传递NSError对象: [myObject performOperationWithError: ]。


共有 人打赏支持
粉丝 10
博文 132
码字总数 287936
×
lightUp
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: