程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Objective-C的對象模型和runtime機制

Objective-C的對象模型和runtime機制

編輯:關於C語言

Objective-C的對象模型和runtime機制


內容列表

對象模型(結構定義,類對象、元類和實例對象的關系) 消息傳遞和轉發機制 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;
};
id類型定義
/// A pointer to an instance of a class.
typedef struct objc_object *id;
Class類型定義
/// 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 
#import 
@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模式查看)

Instance

類對象、元類和實例對象的isa指針調用圖示<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vc3Ryb25nPqOoc3ViY2xhc3MgaXMgYSBpbnN0YW5jZSBvZiBzdXBlcmNsYXNzo6kNCjxwPigxKSBSb290IGNsYXNzIMrHTlNPYmplY3SjrCBOU09iamVjdMO709CzrMDgo6xzdXBlcmNsYXNzIKOtJmd0OyBuaWw8L3A+DQo8cD4oMikgw7+49sDgttTP87a809DSu7j2aXNh1rjP8s6o0ru1xE1ldGEgY2xhc3M8L3A+DQo8cD4oMykgw7+49tSqwOC21M/ztcQgaXNh1rjV67a81rjP8iBOU09iamVjdLXE1KrA4LbUz/M8YnIgLz4NCjxpbWcgYWx0PQ=="這裡寫圖片描述" src="http://www.bkjia.com/uploads/allimg/150723/0434401T6-1.jpg" title="\" />

消息傳遞和轉發機制

消息傳遞(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等功能。

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved