OC對象的本質(下)

1、Instance實例對象內部存貯的是什麼?

(1)、isa 指針

(2)、其他成員變量

2、類對象在內存中存儲的信息主要包含:

  (1)、isa指針

  (2)、superClass指針

  (3)、類的屬性信息(@property)、類的對象方法信息(instance medth)也就是實例方法

  (4)、類的協議信息(@protocol)、類的成員變量信息(ivar)(比如類型和名字)

 

@interface Person:NSObject
{
    @public
    int no;
}
@end
@implementation Person
@end
int main(int argc, const char * argv[]) {
    @autoreleasepool {
      //instance對象,實例對象
        Person *person=[Person new];
        Person *person1=[Person new];
        
        NSLog(@"=====類對象===");
        //class 對象、類對象
        //class 方法返回的一直都是class對象,即類對象
        Class objcClass1=[person class];
        Class objcClass2=[person1 class];
        Class objcClass3=object_getClass(person);
        Class objcClass4=object_getClass(person1);
        Class objectClass5=[Person class];
        //不管調用多少次class返回的都是類對象
        Class objectClass6=[[Person class] class];
        NSLog(@"==類對象==%p==%p==%p==%p==%p==%p",objcClass1,objcClass2,objcClass3,objcClass4,objectClass5,objectClass6);
        
        //meta-class對象,元類對象
        //將類對象當做參數傳入,獲得元類對象
        Class objectMetaClass=object_getClass(objcClass1);
        NSLog(@"===元類對象==%p",objectMetaClass);        

    }
    return 0;
}

運行結果:
==類對象==0x1000011b0==0x1000011b0==0x1000011b0==0x1000011b0==0x1000011b0==0x1000011b0
===元類對象==0x100001188

3、元類對象:

我們可以通過Runtime  API中的object_getClass()方法獲取(將類對象當做參數傳入,獲得元類對象)

每個類對象在內存中有且只有一個元類對象(meta-class)。

meta-class對象和class對象的內存結構都是一樣的,但是用途不一樣,在內存中的存儲的信息主要包括:

(1)、isa指針。

(2)、superclass。

(3)、類的類方法信息(class method)

(注意:我們可以通過class_isMetaClass()方法來判斷是否是元類對象,

   object_getClass()可以傳入三種類型的參數1.實例對象,2.類對象,3.元類對象。

  得到的結果也有三種:

傳入的是實例對象時,獲得是類對象(class 對象)

傳入的是類對象時,獲得是元類對象(meta-class對象)

傳入的是元類對象時,獲得是基類的元類對象(Root-meta-class對象)

4、在OC語言中對象可以分爲三種:

   (1). 實例對象

   (2). 類對象

   (3).元類對象

   實例對象裏面包含:成員變量(實例對象在底層就是結構體)

   類對象包含:isa、superclass、屬性、實例方法、協議、成員變量

   元類對象包含:isa、superclass、類方法

isa指針:

instance的isa指向class類對象

當調用對象方法時,通過instance的isa找到class,最後調用對象方法的實現進行調用。

class的isa指向meta-class

當調用類方法時,通過類對象的isa找到meta-class,最後調用類方法的實現進行調用。

isa、superclass總結:

1、instance的isa指向class

2、class的isa指向meta-class

3、meta-class的isa指向基類的meta-class

4、class的superclass指向父類的class,如果沒有父類,superclass指針爲nil

5、meta-class的superclass指向父類的meta-class,基類的meta-class的superclass指向基類的class

6、instance調用對象方法的軌跡?

      答:isa找到class,方法不存在,就通過superclass找父類直到找到基類class,如果基類還沒有找到這個方法則直接指向nil,拋出異常(沒有找到方法)。

7、class調用類方法的軌跡?

      答:isa找到meta-class,方法不存在,就通過superclass找父類,父類不存在就繼續找直到找到基類的meta-class元類對象,如果基類的元類對象沒有找到類方法就通過superclass指向基類的類對象,如果還沒有找到則指向nil。(拋出異常)

小結

對象的isa指針指向哪裏?

instance對象的isa指針指向類對象。

類對象的isa指針指向元類對象。

元類對象的isa指針指向基類的元類對象。

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章