學(xué)習(xí)ios首先就是要學(xué)習(xí)object-c(以下簡稱OC),雖然現(xiàn)在有了更方便的Swift凫佛,但是萬變不離其宗嘛~讲坎,就像我們有了更高級的C++、Java等面向?qū)ο笳Z言的時候愧薛,我們還是喜歡去研究一下他們的實現(xiàn)原理晨炕,就是為了更好滴把控他。要知道毫炉,只有隨心所欲滴掌控一樣?xùn)|西瓮栗,才可以真正做到為我所用,任我所用瞄勾!此乃為內(nèi)功也费奸!
我剛開始學(xué)習(xí),花了一個星期時間看了這本Objective-C 編程,每天晚上花個兩個小時左右時間进陡,國外原版太貴也不好搞愿阐,只好用翻譯的了。 由于之前學(xué)習(xí)過C語言趾疚,所以前面兩部分工12章幾乎一帶而過缨历。這本書寫的的確不錯,難易有當(dāng)糙麦,適合所有初學(xué)者看辛孵,而且要在實際開發(fā)中不斷滴看。當(dāng)時看完這本書赡磅,還給幾個小伙伴做了簡單的分享觉吭,寫了個很粗糙的PPT
我覺得大部分內(nèi)容都是比較簡單的,有C語言基礎(chǔ)的人仆邓,看起來應(yīng)該好不費事鲜滩。不過我是一個foolish boy嘛,所以還是有一些不懂的地方节值。在此把我不太懂的地方徙硅,也可能是大家比較關(guān)注的幾個問題列出來,并結(jié)合網(wǎng)上資料和自己的理解給個參考答案搞疗,歡迎大家指正嗓蘑。
#include / #import / #@import
OC里面包含頭文件的方式有了import這種方式须肆,那么它到底什么來頭?
我們知道在C桩皿、C++等其他編程語言中豌汇,為了防止某一個頭文件被多次包含,我們會使用#ifndef #define的方式泄隔,在OC中import就自動解決這種問題了拒贱,所以推薦用import(實際上幾乎所有的ios程序都使用import)。有了#import佛嬉,怎么還有一個@import呢逻澳?這又是神馬東東。 這就要提到一個新的特性暖呕,叫做Modules斜做,最基本的作用就是為了加速編譯階段。 #import只是簡單地做代碼替換湾揽,這將無疑增加程序的大小和編譯時間瓤逼,例如一個UIKit框架的代碼就有11000行。@import會在編譯的預(yù)處理階段預(yù)先計算和緩存需要的代碼库物,借此提高代碼的編譯速度霸旗。此外,它還簡化了我們的添加框架的操作艳狐。每個程序至少會用到幾個基本的框架窗宇,我們需要手動去添加這些框架滓玖,萬一忘記了添加某個框架,就會鏈接失敗师妙,我們就需要再去添加框架重新編譯诲侮。有了@import,它會自動幫我們做這些事镀虐,是不是方便又快捷。+ function / - function
第一次看到OC的函數(shù)前的+/- 符號的時候我以為是編譯器自帶的代碼隱藏于顯示的功能沟绪,后來發(fā)現(xiàn)我是圖樣啊刮便。原來,+代表函數(shù)是個靜態(tài)方法绽慈,即可以通過類名直接訪問恨旱;-代表時成員方法,需要實例化對象才能訪問坝疼。類似于C++中的static搜贤。MRC / ARC / AutoReleasepool
OC的內(nèi)存管理不像Java那么方便,但是比C++要方便點钝凶。C++需要自己申請(new/malloc)和釋放(delete/free)資源仪芒,一不小心就會造成內(nèi)存泄漏,Java有自己的內(nèi)存回收機制,無需程序員手動執(zhí)行掂名。OC剛好在兩者之間据沈,它既是自動回收的,也需要程序員的命令饺蔑。
當(dāng)一個對象的擁有方或者說引用計數(shù)為0時锌介,會釋放這個對象資源。
在早期膀钠,OC時需要程序員使用手動引用計數(shù)(MRC, Manual Refrence Counting)的掏湾,維護一個retain計數(shù),程序要顯示地向?qū)ο蟀l(fā)送retain消息肿嘲,例如:
[anObject release]; // anObject失去一個擁有方
[anObject retain]; // anObject得到一個擁有方
這種方式帶來的問題是容易忘記發(fā)送release消息融击,導(dǎo)致內(nèi)存泄漏。特別是大規(guī)模項目中雳窟,這種問題尤為復(fù)雜尊浪。Apple為了結(jié)束這種“內(nèi)存管理黑暗時代”,開發(fā)類一款名為Clang的靜態(tài)分析器封救,可以找到程序中的內(nèi)存泄漏點拇涤。后來,基于此誕生了ARC(Automatic Refrence Counting),顧名思義誉结,就是自動幫你做引用計數(shù)管理了鹅士。
Automatic Reference Counting (ARC) is a compiler feature that provides automatic memory management of Objective-C objects. ARC works by adding code at compile time to ensure that objects live as long as necessary, but no longer. Conceptually, it follows the same memory management conventions as manual reference counting by adding the appropriate memory management calls for you.
自動釋放池是NSAutoreleasePool的實例。其中包含了收到autorelease消息的對象惩坑。當(dāng)一個自動釋放池自身被銷毀(dealloc)時掉盅,它會給池中每一個對象發(fā)送一個release消息(如果你給一個對象多次發(fā)送autorelease消息,那么當(dāng)自動釋放池銷毀時以舒,這個對象也會收到同樣數(shù)目的release消息)趾痘。這是一種延遲釋放的機制,等到釋放池被銷毀的時候釋放所有的對象蔓钟。雖然它表現(xiàn)的好像很自動永票,但是我們不知道它保留的對象真正在什么時候釋放,而且這種延遲釋放在臨時對象很多的時候也是造成很多內(nèi)存的浪費滥沫。
那么問題來了侣集,既然有了ARC,干嘛還要用autoreleasepool兰绣。前者頻繁釋放沒有什么不好啊肚吏,反而后者一起釋放會占用內(nèi)存。是的狭魂,但是前者是在編譯階段干好的時罚攀,當(dāng)我們遇到一些運行時需要解決的問題党觅,比如一個變量橫跨幾個作用域的時候,或者在多線程編程的時候斋泄。我還沒用到過杯瞻,暫且這么記著吧。
-
強引用 / 弱引用
OC中大量使用指針炫掐,就是說一個對象是被另外一個對象指向的魁莉,術(shù)語叫做“擁有”,如果A對象擁有B對象募胃,同時B對象也擁有A對象旗唁,那么就造成一種強引用循環(huán)。這樣導(dǎo)致兩個對象都不能被釋放痹束,從而造成內(nèi)存泄漏检疫。于是乎,弱引用橫空出世了祷嘶。借用書中的說法是:
強引用會保留對象的擁有方屎媳,使其不被釋放;弱引用不會保留對象擁有方论巍。標(biāo)記為弱引用的實例變量或者屬性指向的對象可能會消失烛谊,此時這個實例變量或?qū)傩员恢脼閚il。
用weak屬性可以標(biāo)記弱引用嘉汰,如:
@property (nonatomic, weak) BNREmployee *holder; __weak BNRPerson *parent;
待補充......