iOS 面試題(15):簡(jiǎn)單介紹 ARC 以及 ARC 實(shí)現(xiàn)的原理

注:本文摘自唐巧博客,方便以后查閱。請(qǐng)諒解

問(wèn)題

簡(jiǎn)單介紹 ARC 以及 ARC 實(shí)現(xiàn)的原理。

考查點(diǎn)

ARC 是蘋(píng)果在 WWDC 2011 提出來(lái)的技術(shù),因此很多新入行的同學(xué)可能對(duì)此技術(shù)細(xì)節(jié)并不熟悉。但是,雖然 ARC 極大地簡(jiǎn)化了我們的內(nèi)存管理工作,但是引用計(jì)數(shù)這種內(nèi)存管理方案如果不被理解,那么就無(wú)法處理好那些棘手的循環(huán)引用問(wèn)題。所以,這道面試題其實(shí)是考查同學(xué)對(duì)于 iOS 程序內(nèi)存管理的理解深度。

答案

自動(dòng)的引用計(jì)數(shù)(Automatic Reference Count 簡(jiǎn)稱(chēng) ARC),是蘋(píng)果在 WWDC 2011 年大會(huì)上提出的用于內(nèi)存管理的技術(shù)。

引用計(jì)數(shù)(Reference Count)是一個(gè)簡(jiǎn)單而有效的管理對(duì)象生命周期的方式。當(dāng)我們創(chuàng)建一個(gè)新對(duì)象的時(shí)候,它的引用計(jì)數(shù)為 1,當(dāng)有一個(gè)新的指針指向這個(gè)對(duì)象時(shí),我們將其引用計(jì)數(shù)加 1,當(dāng)某個(gè)指針不再指向這個(gè)對(duì)象是,我們將其引用計(jì)數(shù)減 1,當(dāng)對(duì)象的引用計(jì)數(shù)變?yōu)?0 時(shí),說(shuō)明這個(gè)對(duì)象不再被任何指針指向了,這個(gè)時(shí)候我們就可以將對(duì)象銷(xiāo)毀,回收內(nèi)存。由于引用計(jì)數(shù)簡(jiǎn)單有效,除了 Objective-C 語(yǔ)言外,微軟的 COM(Component Object Model )、C++11(C++11 提供了基于引用計(jì)數(shù)的智能指針 share_prt) 等語(yǔ)言也提供了基于引用計(jì)數(shù)的內(nèi)存管理方式。

引用計(jì)數(shù)這種內(nèi)存管理方式雖然簡(jiǎn)單,但是手工寫(xiě)大量的操作引用計(jì)數(shù)的代碼不但繁瑣,而且容易被遺漏。于是蘋(píng)果在 2011 年引入了 ARC。ARC 顧名思義,是自動(dòng)幫我們填寫(xiě)引用計(jì)數(shù)代碼的一項(xiàng)功能。

ARC 的想法來(lái)源于蘋(píng)果在早期設(shè)計(jì) Xcode 的 Analyzer 的時(shí)候,發(fā)現(xiàn)編譯器在編譯時(shí)可以幫助大家發(fā)現(xiàn)很多內(nèi)存管理中的問(wèn)題。后來(lái)蘋(píng)果就想,能不能干脆編譯器在編譯的時(shí)候,把內(nèi)存管理的代碼都自動(dòng)補(bǔ)上,帶著這種想法,蘋(píng)果修改了一些內(nèi)存管理代碼的書(shū)寫(xiě)方式(例如引入了 @autoreleasepool 關(guān)鍵字)后,在 Xcode 中實(shí)現(xiàn)了這個(gè)想法。

ARC 的工作原理大致是這樣:當(dāng)我們編譯源碼的時(shí)候,編譯器會(huì)分析源碼中每個(gè)對(duì)象的生命周期,然后基于這些對(duì)象的生命周期,來(lái)添加相應(yīng)的引用計(jì)數(shù)操作代碼。所以,ARC 是工作在編譯期的一種技術(shù)方案,這樣的好處是:

  1. 編譯之后,ARC 與非 ARC 代碼是沒(méi)有什么差別的,所以二者可以在源碼中共存。實(shí)際 上,你可以通過(guò)編譯參數(shù) -fno-objc-arc 來(lái)關(guān)閉部分源代碼的 ARC 特性。
  2. 相對(duì)于垃圾回收這類(lèi)內(nèi)存管理方案,ARC 不會(huì)帶來(lái)運(yùn)行時(shí)的額外開(kāi)銷(xiāo),所以對(duì)于應(yīng)用的運(yùn)行效率不會(huì)有影響。相反,由于 ARC 能夠深度分析每一個(gè)對(duì)象的生命周期,它能夠做到比人工管理引用計(jì)數(shù)更加高效。例如在一個(gè)函數(shù)中,對(duì)一個(gè)對(duì)象剛開(kāi)始有一個(gè)引用計(jì)數(shù) +1 的操作,之后又緊接著有一個(gè) -1 的操作,那么編譯器就可以把這兩個(gè)操作都優(yōu)化掉。

但是也有人認(rèn)為,ARC 也附帶有運(yùn)行期的一些機(jī)制來(lái)使 ARC 能夠更好的工作,他們主要是指 weak 關(guān)鍵字。weak 變量能夠在引用計(jì)數(shù)為 0 時(shí)被自動(dòng)設(shè)置成 nil,顯然是有運(yùn)行時(shí)邏輯在工作的。我通常并沒(méi)有把這個(gè)算在 ARC 的概念當(dāng)中,當(dāng)然,這更多是一個(gè)概念或定義上的分歧,因?yàn)槌_(kāi) weak 邏輯之外,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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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