類的結構探索

準備工做

首先咱們建立一個繼承於NSObject的CFPerson類,在mian 函數初始化,再加一個斷點markdown

#import "CFPerson.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...

        CFPerson *person = [CFPerson alloc];

        NSLog(@"Hello, World!  %@",person);
    }
    return 0;
}
複製代碼

接下來看看打印信息函數

當前類信息spa

p/x 0x0000000100002150 拿到元類code

**元類&**0x0000000ffffffff8ULL打印出獲得一個地址orm

在打印元類的指向,可獲得內存信息對象

po 0x00000001003340f0獲得NSObject類繼承

以上打印可分析擬草一個類對象執行過程指向圖:內存

咱們再來驗證一下:get

打印結果發現0x0000000100334140地址不同,並非NSObject類,那麼它可能會是什麼呢?多是第二個NSObject類。it

咱們知道類的信息在內存裏永遠只存在一份。

分析類對象內存存在個數

貼上代碼

void cfTestClassNum(){
    Class class1 = [CFPerson class];
    Class class2 = [CFPerson alloc].class;
    Class class3 = object_getClass([CFPerson alloc]);
    Class class4 = [CFPerson alloc].class;
    NSLog(@"\n%p-\n%p-\n%p-\n%p",class1,class2,class3,class4);
}
複製代碼

看下打印結果:

能夠看出類對象地址都同樣,所以類的信息在內存裏永遠只存在一份

怎樣拿到元類?

首先打印當前地址拿到當前iso,經過當前的iso&ISA_MASK 0x0000000ffffffff8ULL,變可獲得一個地址0x00000001003340f0,於以前po打印的NSObject地址0x00000001003340f0相等,所以它並非NSObject類,而是NSObject元類(根元類)

此刻已經到了根元類,再往下走

繼續打印當前地址iso信息便會獲得根元類的iso,拿到根元類iso再&ISA_MASK 0x0000000ffffffff8ULL獲得地址0x00000001003340f0,再再打印其內存狀況。

此刻咱們發現其內存地址信息與以前的同樣,這便意味着NSObject根元類仍是指向NSObject根元類,即指本身,那麼以前擬草的類對象執行過程指向圖得更新一下了:

對於NSObject沒有元類的指向,其他定義的類都知足實例對象Instance of Superclass[class]——>當前類Subclass[class]——>當前元類Superclass[class]

相關文章
相關標籤/搜索