2016-08-17 14:50:55 660浏览
ARC可以简化代码并增强应用程序的稳定性,它已经成为今后苹果iOS开发的必然趋势,越来越多的项目包括一些第三方库都已经采用了ARC。苹果公司鼓励开发者们使用ARC,AER已经成为iOS开发工程师必备技术职能,但问题并不在于程序员们不想使用ARC——如果0.C从一开始就使用ARC事情反倒好办了,但事实并不是这样。问题在于,以前的代码如何工作在ARC模式F,即非ARC代码如何迁移到ARC?有些代码,比如一些第三方的库,并不是一开始就支持ARC,而要将这些庞大的第三方库都重构为ARC代码,仍然是一个长期和富有挑战性的工作。
因此,由于历史的原因,“ARC”和“非ARC”代码混用的情况仍将在一段时间内继续存在。代码混用的情况一般分为以下两种。
第一,非ARC项目重构为ARC项目,其中有部分代码保持非ARC。
例如,读者手中有一些老的项目(非ARC),需要将它们重构为ARC项目(使用Xcode的重构refactoring功能),但其中又有部分代码不能重构(比如一些非ARC的第三方库,转换起来比较麻烦或者会导致各种各样莫名其妙的问题)。
第二,在ARC项目中添加非ARC的代码。
比如,有一个ARC的项目,读者想导入一些非ARC的代码到这个项目中,这些非ARC的代码暂时不想转换为ARC。
不论是上述哪一种情况,都需要项目能在混合模式下(“ARC”与“非ARC”代码)运行。
1、非ARC项目重构为ARC项目,其中有部分代码保持非ARC
(1)打开非ARC的项目。在aroject设置面板选择target,在Build Settings中将“Compiler forC/C++/0biective—C”设为“Apple LLVM compiler 3.0”或以上。因为ARC只能用Clang进行编译。
(2)还是在Build Settings找到“Objective。C Automatic Reference Counting”,将值改成YES。此时如果编译,编译器会警告无数的错误,暂时不用管它。
(3)单击菜单“Edit—Refactor---Convert to Objective—C ARC”,在“Select Targets To Convert”界面选择target,单击目标名旁边的小箭头,以展开文件列表。
(4)单击右键或【ctrl+左键】选择所有不想重构的文件,如下图所示。
(5)单击【Precheck】按钮进行重构。如果一切正常,则可以进行编译了。
在此列出一些在转换时可能出现的问题,当然在使用ARC时也需要注意在代码中避免这些问题:
·Cast…requires a bridged cast...
ARC“免费桥接”中出现的问题。关于“免费桥接”8.4节会进行详细介绍。
·Receiver type‘X’for instance message is a forward declaration…
前置声明问题。如果在ARC中调用某个子类的方法,而该方法是继承自父类-中的方法(未进行覆盖),则必须导入父类的头文件,否则无法编译。
·Switch case is in protected scope…
现在switch语句必须加上{}了,ARC需要知道局部变量的作用域,加上{J后switch语法更加严格,否则遇到没有break的分支的话内存管理会出现问题。
·A name is referenced outside the NSAutoreleasePool scope that it was declared in…
在非ARC代码中使用了autoreleasepool,转换为ARC代码中则变为@autoreleasepool块,但原来pool中声明的变量在新的@autoreIeaseDool块中作用域将被限制为局部。将变量声明到pool之外即可。
·ARC forbids Objective—C objects in structs or unions…
ARC禁止在C结构体中放入0一C对象。ARC对于结构体和0一C对象指针采用完全不同的处理方式。因为编译器根本不知道一个结构体何时被copy、何时被destroy,也找不到地方去插入retain和release语句,而且将对象指针放到结构中也不是很常见的行为,所以ARC完全放弃了对结构体的管理。如果程序员想将0.c对象指针放到结构体中,必须用unsafe unretained进行修饰,并自己负责对该对象的内存管理以及解决因此产生的一。切问题。切记,通常不应该把O—C指针放入结构体中,如果非要这样做,最好将结构体改变为轻量级的OC类。
2、在ARC项目中添加非ARC的代码
打开ARC项目,转到target的“Build Phases”窗口。
将某个.m文件(不想ARC的)的compiler flags标志修改为-fno-obj-arc(单击该文件旁边的compiler flags栏,然后输入.fno.objc.arc)。这个标志将显示在文件右边,如下图所示。
这样,编译器就会知道凡是带有这个标志的文件都不需要ARC编译。