一直想寫一個整體的Objective-C的帖子,總是沒時間,所以我想把大知識變小,小知識變更小,每天寫一點點,來把自己學習的東西與大家分享,好了廢話不多說。
1、一門動態的語言OC
[對象消息];
但是消息型語言有一個好處,就是它的動態性。其運行時所執行的代碼都是動態的,根據當時運行環境決定。而函數式語言,所執行的代碼編譯階段就已經確定。函數式語言編譯的時候需要查詢函數表才能知道到底運行那段代碼。而消息式語言,編譯時期無需知道該運行哪段代碼,因為它總是到運行的時候,才會去找。它甚至不需要知道消息對象的類型,而這一個過程稱之為“動態綁定”。
所以OC的運行時不同於其他語言,OC重要的工作都在“運行期組件”中完成,OC的所有特性以及內存管理都在“運行期組件”完成,“運行期組件”本質是動態庫。而代碼能把開發者所寫的所有代碼組合起來。這樣的話,只需要更新“運行期組件”就能提高程序性能,而那些函數式語言就需要重新編譯。
2、“堆內存”和“棧內存”
與C++不同,OC不允許將OC對象的內存分配到棧(stack)上,只能分配到堆(heap)上。
C++ string str = "123"; 合法
OC NSString str = @"123";非法
OC必須用一個指針指向一個OC對象,如:
NSString* str = @"123";合法
而大家都知道指針的內存分配到棧上 。
所以例如:
NSString* str2 = str;
這僅僅是進行一次指針的拷貝,並沒有分配新的空間。
用一張圖來描述就是這樣:
系統自動清理。而分配到堆上的內存由程序員來清理。而OC本身實現了引用計數模式管理內存。
但有時候,你會發現有些變量定義不含“ * ”。那麼他們可能會分配在棧上。(id除外,因為它本身已經是指針)
OC是C得超集,完全兼容C所以基本類型和結構體是允許分配到棧上的,比如:
NSInteger CGFloat CGRect CGPoint int double BOOL 等等。
創建結構的開銷遠遠小於對象。如果你對C語言不是太熟悉,那麼你得努力了。
3、引用計數與自動引用計數(ARC)
引用計數是內存管理的一種策略,簡言之,每一個對象需要維護一個整數,這個整數記錄了該對象被引用的次數,如果有新的引用(指針的拷貝)指向該對象,那麼引用計數+1,當失去一個引用的指向時,引用-1,當沒有任何引用指向該對象時,對象被銷毀。
因為OC只允許對象分配到堆上,所以引用計數對於OC非常合適。但是引用計數維護成本略高,而且容易出錯,引用計數過多,造成內存洩露,過少,出現野指針,對於經驗少的程序員,很難做到平衡,需要熟悉這套機制,並且熟悉對應的API。所以高級的編譯器支持自動引用計數,將引用計數的工作交給編譯器,編譯器通過檢測針對引用計數進行控制,但是它也有自己的規則,以後的帖子會講到。
今天就講到這個裡,多謝觀看。
今天的要點:
OC是C得超級,增加了面向對象性,OC使用動態綁定的消息結構,只有運行時才能知道對象的類型,以及需要執行的代碼,不由編譯器決定。
理解堆內存存放的是什麼,棧內存存放的什麼。