Objective-C 對象模型

了解objective-C語言對象模型中對 isa swizzling 和method swizzling 的支持穆律,

isa 指針

在 Objective-C面向?qū)ο笳Z言中睡互,每一個對象都是一個類的示例愤估,實例中包含一個 isa 指針榄棵,指向的是對象所屬的類

@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
    Class isa  OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}

/// Represents an instance of a class.
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

Class 是什么汹胃?

在objc.h 文件中找到class 的定義

/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

從上面源碼中可以看出來 Class 就是一個 objc_class * 結(jié)構(gòu)體指針類型

按住cmd鍵點擊 objc_class 進(jìn)入 runtime.h 中可以看見如下 objc_class 的定義

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
class-isa.png

mateClass(元類)

從上面 objc_class 結(jié)構(gòu)體中可以發(fā)現(xiàn)其中也包含一個 isa 指針蜓洪,在Objective-C語言設(shè)計中胯努,類也是對象牢裳,它屬于另一個類的示例對象,而這里的另一個類所指的就是元類(mateClass)叶沛,元類里面保存了類的對象方法列表蒲讯。元類也是一個,也就是說元類也是一個對象灰署,其中也包含一個 isa 指針判帮,isa 指針?biāo)赶虻氖歉悾╮oot MateClass),根元類的 isa 指針指向的是根元類的本身,這樣使得 Objective-C 語言在設(shè)計上就形成了一個閉環(huán)溉箕。


?? mateClass.png

Class(類)晦墙、MateClass(元類)繼承關(guān)系

前面說過,示例方法保存在類中肴茄,類方方法保存在元類中晌畅,根據(jù)對象在調(diào)用方法的時候,如果類中沒有方法的實現(xiàn)寡痰,則會想它的父類繼續(xù)查找抗楔。為了保證這一點,子類繼承父類拦坠,子類的元類繼承父類的元類连躏。如下圖所示:


Objective-C superClass??.png
  1. 實線表示繼承
  2. 虛線表示 isa 指向

屬性列表

對象方法列表

方法列表存放 objc_class 結(jié)構(gòu)體的 methodLists 中,methodLists 為 objc_method_list 結(jié)構(gòu)體類型贞滨,如下是 objc_method_list 的定義入热,

struct objc_method_list {
    struct objc_method_list * _Nullable obsolete             OBJC2_UNAVAILABLE;

    int method_count                                         OBJC2_UNAVAILABLE;
#ifdef __LP64__
    int space                                                OBJC2_UNAVAILABLE;
#endif
    /* variable length structure */
    struct objc_method method_list[1]                        OBJC2_UNAVAILABLE;
}                                                            OBJC2_UNAVAILABLE;

方法存儲在 method_list ,進(jìn)一步查看 objc_method 的定義

struct objc_method {
    SEL _Nonnull method_name                                 OBJC2_UNAVAILABLE;
    char * _Nullable method_types                            OBJC2_UNAVAILABLE;
    IMP _Nonnull method_imp                                  OBJC2_UNAVAILABLE;
}   

方法列表與分類方法的關(guān)系

對象模型的應(yīng)用

KVO

用一個例子來開始吧

  1. 新建一個名為 KVOTest
@interface KVOTest : NSObject <TestProtocol>
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, assign) NSInteger h;

+ (void)test;
- (void)test;
@end
  1. 創(chuàng)建示例對象

@interface ViewController ()
    @property (nonatomic, strong) KVOTest *test;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    self.test = [[KVOTest alloc] init];
    self.test.age = 50;
    id class = object_getClass(self.test);
    NSLog(@">>>>>>class1:%@", class);
    NSLog(@">>class:%@", self.test.class);
    [self.test addObserver:self forKeyPath:@"age" options:(NSKeyValueObservingOptions)NSKeyValueChangeNewKey context:nil];
    id class1 = object_getClass(self.test);
    NSLog(@">>>>>>class1:%@", class1);
    NSLog(@">>class:%@", self.test.class);
    [self.test addObserver:self forKeyPath:@"h" options:(NSKeyValueObservingOptions)NSKeyValueChangeNewKey context:nil];
    id class2 = object_getClass(self.test);
    NSLog(@">>class:%@", self.test.class);
    NSLog(@">>>>>>class1:%@", class2);
    id MetaClass = objc_getMetaClass("KVOTest");
    NSLog(@"MetaClass :%@",MetaClass);
    // d輸出繼承鏈
    while (class1) {
        class1 = class_getSuperclass(class1);
        NSLog(@">>%@",class1);
    }
}
  1. 輸出結(jié)果
2019-08-09 17:38:50.193966+0800 KVOTest[13656:155097] >>>>>>class1:KVOTest
2019-08-09 17:38:50.194123+0800 KVOTest[13656:155097] >>class:KVOTest
2019-08-09 17:38:50.194560+0800 KVOTest[13656:155097] >>>>>>class1:NSKVONotifying_KVOTest
2019-08-09 17:38:50.194669+0800 KVOTest[13656:155097] >>class:KVOTest
2019-08-09 17:38:50.194902+0800 KVOTest[13656:155097] >>class:KVOTest
2019-08-09 17:38:50.194996+0800 KVOTest[13656:155097] >>>>>>class1:NSKVONotifying_KVOTest
2019-08-09 17:38:50.195088+0800 KVOTest[13656:155097] MetaClass :KVOTest
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市才顿,隨后出現(xiàn)的幾起案子莫湘,更是在濱河造成了極大的恐慌,老刑警劉巖郑气,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件幅垮,死亡現(xiàn)場離奇詭異,居然都是意外死亡尾组,警方通過查閱死者的電腦和手機(jī)忙芒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來讳侨,“玉大人呵萨,你說我怎么就攤上這事】缈纾” “怎么了潮峦?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長勇婴。 經(jīng)常有香客問我忱嘹,道長,這世上最難降的妖魔是什么耕渴? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任拘悦,我火速辦了婚禮,結(jié)果婚禮上橱脸,老公的妹妹穿的比我還像新娘础米。我一直安慰自己,他們只是感情好添诉,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布屁桑。 她就那樣靜靜地躺著,像睡著了一般吻商。 火紅的嫁衣襯著肌膚如雪掏颊。 梳的紋絲不亂的頭發(fā)上糟红,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天艾帐,我揣著相機(jī)與錄音,去河邊找鬼盆偿。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的动猬。 我是一名探鬼主播桶癣,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了今野?” 一聲冷哼從身側(cè)響起葡公,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎条霜,沒想到半個月后催什,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡宰睡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年蒲凶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拆内。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡旋圆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出麸恍,到底是詐尸還是另有隱情灵巧,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布抹沪,位于F島的核電站孩等,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏采够。R本人自食惡果不足惜肄方,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹬癌。 院中可真熱鬧权她,春花似錦、人聲如沸逝薪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽董济。三九已至步清,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間虏肾,已是汗流浹背廓啊。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留封豪,地道東北人谴轮。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像吹埠,于是被迫代替她去往敵國和親第步。 傳聞我的和親對象是個殘疾皇子疮装,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,721評論 0 9
  • 我們常常會聽說 Objective-C 是一門動態(tài)語言粘都,那么這個「動態(tài)」表現(xiàn)在哪呢廓推?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,195評論 0 7
  • 主要參考鏈接: http://yulingtianxia.com/blog/2014/11/05/objectiv...
    Kevin_Junbaozi閱讀 3,313評論 0 10
  • 這兩年來,一直是處于一種對老去的焦慮狀態(tài)翩隧∈苌叮或者說,一種到了自己預(yù)設(shè)的年齡鸽心,卻沒有做到自己預(yù)設(shè)的事情而感到無比抑郁的...
    公子F閱讀 313評論 0 0
  • 關(guān)于帶兵這個問題滚局,韓信曾指出漢高祖劉邦能帶十萬人馬,而劉邦問韓信能帶多少兵時顽频,韓信淡定自若地回答“多多益善”藤肢,而歷...
    凱夫拉閱讀 974評論 0 2