標籤:
內容列表
- 物件模型(結構定義,類對象、元類和執行個體對象的關係)
- 訊息傳遞和轉寄機制
- runtime系統功能理解
物件模型結構定義
對象(Object): OC中基本構造單元 (building block),用於儲存和傳遞資料。
能夠在objc.h的檔案裡尋找到對象結構的定義,例如以下所看到的即對象結構為Class類型的isa,而Class是 objc_class結構類型指標。
objc_class即我們理解的類對象結構。其也包含一個isa類對象結構指標。
類和對象的終於實現都是一種資料結構,(subclass is an instance of superclass)
/// Represents an instance of a class.struct objc_object { Class isa OBJC_ISA_AVAILABILITY;};
/// A pointer to an instance of a class.typedef struct objc_object *id;
/// An opaque type that represents an Objective-C class.typedef struct objc_class *Class;
struct objc_class { Class isa OBJC_ISA_AVAILABILITY;#if !__OBJC2__ Class super_class OBJC2_UNAVAILABLE; const char *name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; struct objc_method_list **methodLists OBJC2_UNAVAILABLE; struct objc_cache *cache OBJC2_UNAVAILABLE; struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;#endif} OBJC2_UNAVAILABLE;
類(類對象)、元類(元類對象)和執行個體對象的關係
一個完整的類應該包含類方法、執行個體方法和成員變數(執行個體變數), 每一個對象都包含一個isa(is a class)指標指向類對象(執行時方法發送給對象訊息,才確定類別並調用相應的方法實現
)。類對象結構中記載了類的全部資訊。
類對象的isa指向元類對象(meta class),類對象中的方法列表是執行個體方法(-, instance methods)。 元類對象中的方法列表是類方法(+, class methods)
- 能夠這麼理解:
類包含類對象和元類對象,它們通過類對象結構定義,構成類的全部資訊。在定義執行個體對象的時候,並不會進行不論什麼儲存空間(堆)分配,直到調用類方法alloc函數和執行個體方法init函數實現執行個體對象在堆中的結構儲存分配。並將isa指向其類對象。父類成員變數和相應類對象成員變數初始化為0或nil
上述理解能夠通過以下代碼和物件變數結構分析來進行確認。
#import <Foundation/Foundation.h>#import <objc/runtime.h>@interface AClass : NSObject{ int a; char cA;}- (void)printA;@end@implementation AClass- (void)printA{ NSLog(@"I am class A~");}@end@interface BClass : AClass{ int b; char cB;}- (void)printB;@end@implementation BClass- (void)printB{ NSLog(@"I am class B~");}@end// ---------- main ----------int main(int argc, const char * argv[]) { @autoreleasepool { // ******物件模型初探****** AClass *a = [[AClass alloc] init]; BClass *b = [[BClass alloc] init]; BClass *b1; [a printA]; [b printB]; } return 0; }
- 查看物件變數結構(通過設定斷點進入Debug模式查看)
- 類對象、元類和執行個體對象的isa指標調用圖示(subclass is a instance of superclass)
(1) Root class 是NSObject, NSObject沒有超類。superclass -> nil
(2) 每一個類對象都有一個isa指向唯一的Meta class
(3) 每一個元類對象的 isa指標都指向 NSObject的元類對象
訊息傳遞和轉寄機制
訊息傳遞(Messaging): 在對象之間傳遞資料並執行任務的過程
Objective-C基於C語言加入了物件導向特性和訊息轉寄機制的動態語言。除編譯器外還須要用Runtime系統來動態建立類和對象進行訊息發送和轉寄。
不同語言有不同函數傳遞方法,C語言 - 函數指標,C++ - 函數調用(引用)類成員函數在編譯時間候就確定了其所屬類別, Objective-C 通過選取器和block。
Objective-C強調訊息傳遞而非方法調用。
能夠向一個對象傳遞訊息,且不須要再編譯期聲明這些訊息的處理方法。
這些方法在執行時才確定。執行時(runtime)詳細功能將在以下介紹。
[receiver message];
並不會立即執行 receiver 對象的 message方法的代碼。而是向receiver發送一條message訊息,該句話被編譯器轉化為:
id obj_msgSend(id self, SEL op, …);
PS: 訊息調用函數還存在特殊情況,如其它函數
objc_msgSend_stret //待發送訊息返回結構體
objc_msgSend_fpret //返回浮點數
objc_msgSendSuper //給超類發訊息
SEL 表示方法選取器,結構例如以下: typedef struct objc_selector*SEL。
, 可通過關鍵字@selector()獲得
id 資料結構在第一部分:物件模型
中已經有定義。
obj_msgSend 發訊息流程程:
- 依據receiver 對象的isa類對象指標擷取相應的class(類對象);
- 優先在類對象的cache(fast map)尋找message方法,Not find ->再到methodLists(類中的調度表,用於映射方法和實際記憶體位址。同一時候類中還包含指向父類的指標)尋找;
- 假設沒有在class象裡找到。再到super_class尋找。
- 假設找到message這種方法,執行它的實現IMP
- 假設找不到訊息。則執行訊息轉寄(message forwarding)
Method資料結構
runtime.h標頭檔裡定義:
typedef struct objc_method *Method;struct objc_method { SEL method_name; // 特殊的字串。描寫敘述方法名, 能夠通過關鍵字 @selector( ) 擷取 char *method_types; IMP method_imp;}
PS:訊息轉寄分為兩大階段即動態加入方法解析(dynamic method resolution)和完整的訊息轉寄機制(full forward mechanism)
runtime系統功能理解
runtime : 程式執行後。提供相關支援的代碼叫做OC執行期環境(OC runtime)
,它提供了對象間傳遞訊息的重要函數(比方objc_msgSend),而且包含建立類執行個體所用的全部邏輯(即建立執行個體對象的儲存結構和空間,包含isa指向“類對象”的指標)
runtime系統是一個用C語言編寫動態連結程式庫,核心是訊息分發。Runtime機制包含物件模型。訊息傳遞和轉寄。方法實現機制和其它執行時方法。能夠實現動態建立改動類對象和對象等功能,訊息傳遞和轉寄,方法動態實現,Method Swizzling等功能。
##Objective-C程式產生目標檔案裡的執行時資訊怎樣擷取?
對於一個OC的.m程式檔案,在Terminal輸入命令:
gcc -framework Foundation main.m -o p1
當然。執行命令即: ./p1
然後,通過 otool 工具擷取目標檔案(包含頭部、載入指令、各個segment)中執行時資訊(有專門的segment儲存)
otool -o p1
PS 我們能夠通過擷取執行時資訊瞭解物件模型中元類對象和類對象結構等資訊,例如以下所看到的。能夠清晰看到類對象列表和元類映射關係,結構資訊
p1:Contents of (__DATA,__objc_classlist) section0000000100001098 0x100001310 isa 0x1000012e8 superclass 0x0 cache 0x0 vtable 0x0 data 0x100001160 (struct class_ro_t *) flags 0x0 instanceStart 8 instanceSize 13 reserved 0x0 ivarLayout 0x0 name 0x100000f60 AClass baseMethods 0x1000010f8 (struct method_list_t *) entsize 24 count 1 name 0x100000f6e printA types 0x100000f91 [email protected]0:8 imp 0x100000d90 baseProtocols 0x0 ivars 0x100001118 entsize 32 count 2 offset 0x1000012c8 8 name 0x100000f75 a type 0x100000f99 i alignment 2 size 4 offset 0x1000012d0 12 name 0x100000f77 cA type 0x100000f9b c alignment 0 size 1 weakIvarLayout 0x0 baseProperties 0x0Meta Class isa 0x0 superclass 0x0 cache 0x0 vtable 0x0 data 0x1000010b0 (struct class_ro_t *) flags 0x1 RO_META instanceStart 40 instanceSize 40 reserved 0x0 ivarLayout 0x0 name 0x100000f60 AClass baseMethods 0x0 (struct method_list_t *) baseProtocols 0x0 ivars 0x0 weakIvarLayout 0x0 baseProperties 0x000000001000010a0 0x100001360 isa 0x100001338 superclass 0x100001310 cache 0x0 vtable 0x0 data 0x100001258 (struct class_ro_t *) flags 0x0 instanceStart 16 instanceSize 21 reserved 0x0 ivarLayout 0x0 name 0x100000f67 BClass baseMethods 0x1000011f0 (struct method_list_t *) entsize 24 count 1 name 0x100000f7a printB types 0x100000f91 [email protected]0:8 imp 0x100000dc0 baseProtocols 0x0 ivars 0x100001210 entsize 32 count 2 offset 0x1000012d8 16 name 0x100000f81 b type 0x100000f99 i alignment 2 size 4 offset 0x1000012e0 20 name 0x100000f83 cB type 0x100000f9b c alignment 0 size 1 weakIvarLayout 0x0 baseProperties 0x0Meta Class isa 0x0 superclass 0x1000012e8 cache 0x0 vtable 0x0 data 0x1000011a8 (struct class_ro_t *) flags 0x1 RO_META instanceStart 40 instanceSize 40 reserved 0x0 ivarLayout 0x0 name 0x100000f67 BClass baseMethods 0x0 (struct method_list_t *) baseProtocols 0x0 ivars 0x0 weakIvarLayout 0x0 baseProperties 0x0Contents of (__DATA,__objc_classrefs) section00000001000012b8 0x10000131000000001000012c0 0x100001360Contents of (__DATA,__objc_imageinfo) section version 0 flags 0x0
參考資源
Effective Objective-C 2.0
Objective-C的物件模型與執行時
深入理解Objective-C的Runtime機制
Objective-C的動態特性
Objective-C的物件模型和runtime機制