2016-08-17 14:50:55 1655瀏覽
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編譯。