OC 語言由 Smalltalk (消息型語言的鼻祖) 演化而來。OC 使用“消息結構”(messaging structure),而非“函數調用”(function calling)。
關鍵區別:
消息結構語言:運行時應執行代碼由運行環境決定;
函數調用語言:由編譯器決定。
OC 的重要工作都由“運行期組件”(runtime component)而非編譯器完成。
OC 是 C 的“超集”(superset),C 語言的所有功能在 OC 依然適用。
OC 中的指針是指示對象的。想要聲明一個變量,令其指代某個對象,語法如下:
NSString *someString = @"The string";
//聲明一個名為 someString 的變量,其類型是 NSString*, 即此變量為指向 NSString 的指針。
對象所占內存分配在“堆空間(heap space)”,絕不會分配在“??臻g(stack space)”,不能在棧中分配 OC 對象。
someString 變量指向分配在堆里的某塊內存,其中含有一個 NSString 對象。若再創建一個變量,令其指向同一地址,并不拷貝該對象,只是兩個變量同時指向該對象:
NSString *someString = @"The string";
NSString *anotherString = someString;
只有一個 NSString 實例,兩個變量指向此實例,都是 NSString* 類型。說明當前“棧幀”(stack frame)里分配了兩塊內存,每塊大小都能容下一枚指針(32位架構的計算機上是4字節,64位計算機是8字節),兩塊內存里的值一樣,都是 NSString 實例的內存地址。
分配在堆中的內存必須直接管理,而分配在棧上用于保存變量的內存則會在其棧幀彈出時自動清理。OC 將堆內存管理抽象出來了,不需要 malloc 和 free 來分配和釋放內存。OC 運行期環境把這部分工作抽象為一套內存管理架構,名為“引用計數”。
OC 中有些不含 * 的變量,可能會用到“??臻g”(stack space),這些變量保存的不是 OC 對象,例如 CoreGraphics 中的 CGRect:
CGRect frame;
frame.origin.x = 0.0f;
frame.origin.y = 1.0f;
frame.size.width = 100.0f;
frame.size.height = 150.0f;
CGRect 是 C 結構體,其定義:
struct CGRect {
CGPoint origin;
CGSize size;
};
typedef struct CGRect CGRect;
整個系統框架都在使用這種結構體。
原因:若改用 OC 對象來做的話,性能會受影響(與創建結構體相比,創建對象還需額外開銷)。
要點:
- OC 為 C 語言添加了面向對象特性,是其超集。OC 使用動態綁定的消息結構,即,運行時才會檢查對象類型。收到一條消息后,該執行何種代碼,由運行期環境而非編譯器決定。
- 理解 C 語言的核心概念有助于寫好 OC 程序。尤其要掌握內存模型和指針。
PS: 初讀這么有含量的書,加之 C 語言基礎有點薄弱,覺得信息量好大。許多不理解的暫且記下,待日后慢慢消化吸收。