MRC轉(zhuǎn)ARC

春節(jié)前抽空花了一天的時(shí)間將手頭的工程從MRC轉(zhuǎn)成了ARC,然后陸陸續(xù)續(xù)地修復(fù)一部分因?yàn)檗D(zhuǎn)ARC引起的內(nèi)存泄漏和崩潰,到目前為止工程也算是比較穩(wěn)定了,抽空記上一筆。(雖說這種事情這輩子估計(jì)都只會(huì)做這么一次了,但是可以留點(diǎn)經(jīng)驗(yàn)給后來的童鞋)

這個(gè)工程啟動(dòng)于12年底13年初,一開始人手少工期短,需要盡快地出demo,同時(shí)抱著對(duì)面世才一年多的ARC不太信任的態(tài)度沿用了最熟悉的MRC。但是隨著工程投入的人手增多,使用MRC的各種缺點(diǎn)也暴露無遺:

零星的內(nèi)存泄漏增多,導(dǎo)致每次發(fā)版本之前都要捋一遍:費(fèi)時(shí)費(fèi)力不討好。雖然我一直覺得iOS下這種零星的內(nèi)存泄漏并不是多大的事,真正壓死一個(gè)App的泄漏永遠(yuǎn)是某些Bitmap的泄漏。但是這種零星泄漏仍舊會(huì)帶來很多麻煩,所以還是需要解決一下。

無法享受到ARC下weak關(guān)鍵字帶來的好處:總有童鞋忘記在對(duì)象析構(gòu)時(shí)去置空delegate。系統(tǒng)控件如UIScrollView,MKMapView的delegate仍舊需要自己釋放,但是自定義procotol并將屬性設(shè)為weak的delegate就可以獲得weak屬性帶來的好處。

ARC下編譯器對(duì)于retain cycle的檢測(cè)更為嚴(yán)格。(個(gè)人使用后的感覺)

越來越多的第三方庫只提供ARC版本,雖然打標(biāo)記可以解決問題,但增加了無謂的工作。

基于以上4點(diǎn)理由,于是選了春節(jié)前一個(gè)月高風(fēng)黑夜悄悄地完成工程的ARC轉(zhuǎn)換。23333333333333333

準(zhǔn)備工作

1.一個(gè)MRC模式的工程。(嗯!)

2.一個(gè)合適版本的XCode。(你是雞???不,我是喜兒肉絲)雖然XCode4之后就支持了ARC的自動(dòng)轉(zhuǎn)換,但是對(duì)ObjC++的支持卻還是在XCode5之后。

3.一臺(tái)性能彪悍的機(jī)器。個(gè)人悲慘經(jīng)歷:某天下午用自己那臺(tái)老爺機(jī)做了一次轉(zhuǎn)換,結(jié)果在最后一步機(jī)器直接卡死,重啟后XCode也無法使用,最后只得重裝XCode了事。

使用XCode做最基本的轉(zhuǎn)換

1.開啟即使出錯(cuò)也繼續(xù)編譯的選項(xiàng):”Preferences” -> “General” -> “continue building after error” 。當(dāng)轉(zhuǎn)換開始后工程將出現(xiàn)大量的錯(cuò)誤,與其每次fix一個(gè)錯(cuò)誤再來一遍,還不如一口氣讓編譯器把所有的錯(cuò)誤都先匯報(bào)出來,再一一解決。(我們的工程大約20來萬代碼,檢查出了近200個(gè)錯(cuò)誤)

2.檢查第三方庫和自己的代碼。對(duì)于第三方庫,有ARC版本就進(jìn)行替換,沒有則打上-fno-objc-arc的標(biāo)記(當(dāng)然如果第三方庫比較簡(jiǎn)單,也可以直接做轉(zhuǎn)換)。而自己的代碼則推薦全部做ARC的轉(zhuǎn)換。

3.使用XCode提供的Convert to Objective-C ARC功能,選擇當(dāng)前需要轉(zhuǎn)換的工程并執(zhí)行。

4.正常情況會(huì)出現(xiàn)比較多的錯(cuò)誤和retain-cycle的warning,推薦優(yōu)先解決掉所有error,而warning暫時(shí)不處理,等轉(zhuǎn)換完畢編譯通過后再進(jìn)行處理。而error和warning一般也就是下面幾種情況:

對(duì)于NSObject和CF對(duì)象沒有使用bridge cast,大多數(shù)情況下直接按照XCode的推薦方式進(jìn)行fix即可。

原來MRC下使用了ARC下不允許使用的方法,如NSMakeCollectable。

原先使用__block關(guān)鍵字避免循環(huán)引用的地方在ARC往往會(huì)引起循環(huán)引用,原因是__block在MRC和ARC下的語意不同,MRC下生成的__block結(jié)構(gòu)體內(nèi)只是簡(jiǎn)單地指向原值地址,而ARC下則是由__block結(jié)構(gòu)體持有了原值,使用__weak進(jìn)行修改即可。

處理完畢后重復(fù)第三步直到順利編譯通過。

后續(xù)處理

完成前面的步驟整個(gè)轉(zhuǎn)換就算完成了百分之九十,但是正所謂行百里者半九十,接下去的任務(wù)更加艱巨,更需要認(rèn)真對(duì)待。

1.檢查工程內(nèi)的所有文件,包括是否設(shè)置了合理的編譯選項(xiàng)和被包含在工程內(nèi):XCode似乎有個(gè)bug,在轉(zhuǎn)換完成后部分文件會(huì)被移出工程,部分文件原先打好的-fno-objc-arc標(biāo)記也會(huì)被重置。

2.運(yùn)行Instrument,檢查內(nèi)存泄漏:此時(shí)存在的內(nèi)存泄漏大多是一些對(duì)ARC不適用的MRC寫法。典型的情況便是將delegate作為類內(nèi)部成員變量,在轉(zhuǎn)換為ARC后系XCode并不會(huì)在這些變量前面打上weak的標(biāo)記,導(dǎo)致了循環(huán)引用,需要自己手動(dòng)添加。

3.對(duì)你的程序進(jìn)行冒煙,盡量走完主流程,檢查是否有必現(xiàn)崩潰。一般都是由錯(cuò)誤的bridge cast和使用MRC時(shí)的不規(guī)范寫法引起:如萬惡的[self retain],在ARC轉(zhuǎn)換時(shí)XCode直接去掉這句話,這樣就導(dǎo)致原先依賴于此的類往往在初始化后就直接被釋放,造成野指針訪問。(吐槽下,無論是MRC還是ARC下,自己去擁有自己這種做法都是不太好的做法)

4.扔給QA繼續(xù)測(cè)試……23333333333333333333333

原文鏈接?MRC工程轉(zhuǎn)ARC工程小記

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ARC中: 1、可以說ARC所引入的最嚴(yán)格的限制是不能在C結(jié)構(gòu)體中放OC對(duì)象了..因此類似下面這樣的代碼是不可用的...
    然亦傘閱讀 489評(píng)論 1 1
  • 什么是Automatic Reference Counting? Automatic Reference Coun...
    癲癲的戀了閱讀 3,259評(píng)論 3 23
  • 不要等到明天,明天太遙遠(yuǎn),今天就行動(dòng)。 須讀:看完該文章你能做什么? 如何將一個(gè)MRC的項(xiàng)目 轉(zhuǎn)成 ARC 學(xué)習(xí)前...
    liyuhong閱讀 431評(píng)論 0 0
  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,626評(píng)論 30 472
  • 自動(dòng)引用計(jì)數(shù)(ARC)是一項(xiàng)編譯器功能,可以給Objective-C提供自動(dòng)內(nèi)存管理的能力。ARC使得程序員能專注...
    hlwz5735閱讀 1,824評(píng)論 0 3

友情鏈接更多精彩內(nèi)容