MRC轉ARC

春節前抽空花了一天的時間將手頭的工程從MRC轉成了ARC,然后陸陸續續地修復一部分因為轉ARC引起的內存泄漏和崩潰,到目前為止工程也算是比較穩定了,抽空記上一筆。(雖說這種事情這輩子估計都只會做這么一次了,但是可以留點經驗給后來的童鞋)

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

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

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

ARC下編譯器對于retain cycle的檢測更為嚴格。(個人使用后的感覺)

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

基于以上4點理由,于是選了春節前一個月高風黑夜悄悄地完成工程的ARC轉換。23333333333333333

準備工作

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

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

3.一臺性能彪悍的機器。個人悲慘經歷:某天下午用自己那臺老爺機做了一次轉換,結果在最后一步機器直接卡死,重啟后XCode也無法使用,最后只得重裝XCode了事。

使用XCode做最基本的轉換

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

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

3.使用XCode提供的Convert to Objective-C ARC功能,選擇當前需要轉換的工程并執行。

4.正常情況會出現比較多的錯誤和retain-cycle的warning,推薦優先解決掉所有error,而warning暫時不處理,等轉換完畢編譯通過后再進行處理。而error和warning一般也就是下面幾種情況:

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

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

原先使用__block關鍵字避免循環引用的地方在ARC往往會引起循環引用,原因是__block在MRC和ARC下的語意不同,MRC下生成的__block結構體內只是簡單地指向原值地址,而ARC下則是由__block結構體持有了原值,使用__weak進行修改即可。

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

后續處理

完成前面的步驟整個轉換就算完成了百分之九十,但是正所謂行百里者半九十,接下去的任務更加艱巨,更需要認真對待。

1.檢查工程內的所有文件,包括是否設置了合理的編譯選項和被包含在工程內:XCode似乎有個bug,在轉換完成后部分文件會被移出工程,部分文件原先打好的-fno-objc-arc標記也會被重置。

2.運行Instrument,檢查內存泄漏:此時存在的內存泄漏大多是一些對ARC不適用的MRC寫法。典型的情況便是將delegate作為類內部成員變量,在轉換為ARC后系XCode并不會在這些變量前面打上weak的標記,導致了循環引用,需要自己手動添加。

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

4.扔給QA繼續測試……23333333333333333333333

原文鏈接?MRC工程轉ARC工程小記

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

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