包羅萬象的runtime(一):對象&類&元類

蘋果官方維護(hù)的objc源代碼

我們常說OC是一種面向?qū)ο蟮恼Z言,那么
什么是對象顽腾?

:對同一類事物的高度抽象际乘。類定義了這一類的屬性以及行為準(zhǔn)則(方法)。
對象:類的一個實(shí)例衔肢,是一個具體的事物颠通。

1. runtime中的類和對象

typedef struct objc_class *Class;
typedef struct objc_object *id;

簡單從定義來看:Class是一個objc_class結(jié)構(gòu)類型的指針,id(任意對象)是一個objc_object結(jié)構(gòu)類型的指針
再來看下這兩個結(jié)構(gòu)體objc_classobjc_object

/// objc_class
struct objc_class {
    Class isa;
    Class super_class;
    const char *name;
    long version;
    long info;
    long instance_size;
    struct objc_ivar_list *ivars;
    struct objc_method_list *methodLists;
    struct objc_cache *cache;
    struct objc_protocol_list *protocols;
} ;
/// objc_object
struct objc_object {
    Class isa;
};

objc_class和objc_object都有一個isa指針膀懈,我們知道實(shí)例的isa指針指向?qū)嵗鶎俚念惗倜蹋磑bjc_object中的isa指針指向了objc_object所屬的類objc_class,那么
objc_class中的isa指針指向哪里呢启搂?

2. 元類 MetaClass

先看結(jié)論

每一個類本質(zhì)上都是一個對象硼控,類其實(shí)是元類(meteClass)的實(shí)例。類通過類的isa指針指向元類胳赌。所有的元類最終繼承一個根元類牢撼,根元類isa指針指向本身,形成一個封閉的內(nèi)循環(huán)疑苫。

看到這里我又疑惑了熏版,實(shí)例的isa指向它所屬的類,類的isa指向它的元類捍掺,類的元類是什么撼短,是它所繼承的父類嗎,那么類的isa(元類)和super_class(父類)是不是有關(guān)系呢挺勿?
還是要來段代碼測試一下:

Class class1 = [[NSString alloc] init].class;
Class class = [NSString class];
Class superClass = [NSString superclass];
NSLog(@"%@:%p",NSStringFromClass(class1), class1);
NSLog(@"%@:%p",NSStringFromClass(class), class);
NSLog(@"%@:%p",NSStringFromClass(superClass), superClass);
//輸出結(jié)果
2018-06-02 08:17:46.802684+0800 RuntimeDemo[1129:82727] __NSCFConstantString:0x108679fe0
2018-06-02 08:17:46.802851+0800 RuntimeDemo[1129:82727] NSString:0x107abad68
2018-06-02 08:17:46.802989+0800 RuntimeDemo[1129:82727] NSObject:0x1080feea8

測試發(fā)現(xiàn)曲横,NSString的元類([NSString class])并不是我以為的NSObject,而是NSString,那么實(shí)例的isa指針和類的isa指針指向到底哪里不一樣呢?還是code一下看看吧
先寫個方法輸出Class的詳細(xì)信息

- (void)getInfoFromClass:(Class)cls {
    /// class_getName 獲取類name
    NSLog(@"%s:%p",class_getName(cls), cls);
    /// class_isMetaClass用于判斷Class對象是否為元類禾嫉,
    BOOL isMeta = class_isMetaClass(cls);
    NSLog(@"%@",isMeta?@"是元類":@"不是元類");
    // 成員變量
    unsigned int outCount = 0;
    NSLog(@"成員變量 class_copyIvarList:");
    Ivar *ivars = class_copyIvarList(cls, &outCount);
    for (int i = 0; i < outCount; i++) {
        Ivar ivar = ivars[i];
        NSLog(@"%s",ivar_getName(ivar));
    }
    free(ivars);
    
    // 屬性操作
    NSLog(@"屬性 class_copyPropertyList:");
    objc_property_t * properties = class_copyPropertyList(cls, &outCount);
    for (int i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        NSLog(@"%s", property_getName(property));
    }
    free(properties);
    
    // 方法操作
    NSLog(@"方法 class_copyMethodList:");
    Method *methods = class_copyMethodList(cls, &outCount);
    for (int i = 0; i < outCount; i++) {
        Method method = methods[i];
        SEL sel = method_getName(method);
        NSLog(@"%@",NSStringFromSelector(sel));
    }
    free(methods);
}

再自定義個Person類(這里為什么不用系統(tǒng)的類呢灾杰,因為系統(tǒng)的類方法太多了,輸出那么多影響觀察)

#pragma mark - 定義一個類Person
@interface Person : NSObject

+ (void)staticDescription;

- (void)instanceDescription;

@end

@implementation Person
+ (void)staticDescription { }

- (void)instanceDescription { }
@end

OK熙参,定義了一個類Person艳吠,Person包含一個類方法一個實(shí)例方法,打印一下看看

Person *person = [[Person alloc] init];
/// object_getClass用于獲取對象的isa指針指向的對象孽椰。
[self getInfoFromClass:object_getClass(person)];
[self getInfoFromClass:object_getClass(Person.class)];
/// 輸出結(jié)果
2018-06-02 09:32:32.473784+0800 RuntimeDemo[2398:280748] Person:0x109bf7010
2018-06-02 09:32:32.473922+0800 RuntimeDemo[2398:280748] 不是元類
2018-06-02 09:32:32.474260+0800 RuntimeDemo[2398:280748] 方法 class_copyMethodList:
2018-06-02 09:32:32.474382+0800 RuntimeDemo[2398:280748] instanceDescription
2018-06-02 09:32:32.474484+0800 RuntimeDemo[2398:280748] Person:0x109bf6fe8
2018-06-02 09:32:32.474635+0800 RuntimeDemo[2398:280748] 是元類
2018-06-02 09:32:32.474960+0800 RuntimeDemo[2398:280748] 方法 class_copyMethodList:
2018-06-02 09:32:32.475084+0800 RuntimeDemo[2398:280748] staticDescription

看到了吧讲竿,實(shí)例的isa指針指向它所屬的類,類的isa指針指向的是類對象的元弄屡。類對象存的是關(guān)于實(shí)例對象的信息(變量,實(shí)例方法等)鞋诗,而元類對象(metaclass object)中存儲的是關(guān)于類的信息(類的版本膀捷,名字,類方法等)削彬。

所以類也是對象全庸,是元類的對象

類對象和實(shí)例對象的區(qū)別:盡管類對象保留了一個類實(shí)例的原型,但它并不是實(shí)例本身融痛。它沒有自己的實(shí)例變量壶笼,也不能執(zhí)行那些類的實(shí)例的方法(只有實(shí)例對象才可以執(zhí)行實(shí)例方法)。然而雁刷,類的定義能包含那些特意為類對象準(zhǔn)備的方法–類方法( 而不是的實(shí)例方法)覆劈。類對象從父類那里繼承類方法,就像實(shí)例從父類那里繼承實(shí)例方法一樣沛励。

來看下說明圖:


image.png

參考鏈接:
http://www.reibang.com/p/41735c66dccb
http://justsee.iteye.com/blog/2163905
http://www.zhimengzhe.com/IOSkaifa/253119.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末责语,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子目派,更是在濱河造成了極大的恐慌坤候,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件企蹭,死亡現(xiàn)場離奇詭異白筹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)谅摄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進(jìn)店門徒河,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人送漠,你說我怎么就攤上這事虚青。” “怎么了螺男?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵棒厘,是天一觀的道長纵穿。 經(jīng)常有香客問我,道長奢人,這世上最難降的妖魔是什么谓媒? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮何乎,結(jié)果婚禮上句惯,老公的妹妹穿的比我還像新娘。我一直安慰自己支救,他們只是感情好抢野,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著各墨,像睡著了一般指孤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贬堵,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天恃轩,我揣著相機(jī)與錄音,去河邊找鬼黎做。 笑死叉跛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蒸殿。 我是一名探鬼主播筷厘,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼宏所!你這毒婦竟也來了敞掘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤楣铁,失蹤者是張志新(化名)和其女友劉穎玖雁,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盖腕,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赫冬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了溃列。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片劲厌。...
    茶點(diǎn)故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖听隐,靈堂內(nèi)的尸體忽然破棺而出补鼻,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布风范,位于F島的核電站咨跌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏硼婿。R本人自食惡果不足惜锌半,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望寇漫。 院中可真熱鬧刊殉,春花似錦、人聲如沸州胳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽栓撞。三九已至遍膜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間腐缤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工肛响, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留岭粤,地道東北人。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓特笋,卻偏偏與公主長得像剃浇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子猎物,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評論 2 355

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