iOS 深入理解isa指針和superclass指針

一枚粘、通過源碼理解instance(實(shí)例對象) 荣茫、class object (類對象)厂捞、metaclass(元類對象)

蘋果開源代碼(https://opensource.apple.com/tarballs/)

1.instance 實(shí)例對象

1.1定義

實(shí)例對象是通過類alloc出來的對象,每次調(diào)用alloc都會(huì)產(chǎn)生新的實(shí)例對象

NSObject *object1 = [[NSObject alloc] init];
NSObject *object2 = [[NSObject alloc] init];

以上object1檀葛、object2都是實(shí)例對象玩祟,占用兩塊兒不同的內(nèi)存

1.2、底層實(shí)現(xiàn)

首先屿聋,終端定位到需要轉(zhuǎn)化文件的文件夾下空扎,用以下命令行將OC代碼轉(zhuǎn)成C++/C代碼

xcrun  -sdk  iphoneos  clang  -arch  arm64  -rewrite-objc  OC源文件  -o  輸出的CPP文件

以NSObject對象為例,我們用以上方法看看它的底層實(shí)現(xiàn)

int main(int argc, const char * argv[]) {
@autoreleasepool {
    NSObject *obj = [[NSObject alloc] init];
}
return 0;
}

轉(zhuǎn)成C++代碼后润讥,我們找到了這個(gè)對象的實(shí)現(xiàn)

struct NSObject_IMPL {
Class isa;
};
//Class是指針類型转锈,指向objc_class類型的結(jié)構(gòu)體
typedef struct objc_class *Class;

obj對象內(nèi)部實(shí)際上只有一個(gè)isa指針,指向objc_class類型的結(jié)構(gòu)體楚殿。 那isa指針到底指向誰撮慨,它又有什么用呢? 在下文中我們會(huì)講到

1.3勒魔、更復(fù)雜的繼承結(jié)構(gòu)

我們舉一反三甫煞,設(shè)計(jì)一個(gè)父類Father,繼承于NSObject冠绢,再設(shè)計(jì)一個(gè)子類son繼承于父類抚吠,看看他們的底層實(shí)現(xiàn)

@interface Father : NSObject {
    int _age;
}
@end

@interface Son : Father {
   double _height;
}
@end

把代碼轉(zhuǎn)成C++,看看內(nèi)部實(shí)現(xiàn)弟胀。直接查找類名_IMPL

struct Father_IMPL {
    struct NSObject_IMPL NSObject_IVARS;
    int _age;
};

struct Son_IMPL {
    struct Father_IMPL Father_IVARS; 
    double _height;
};

上述代碼相當(dāng)于

struct Father_IMPL {
    Class isa;
    int _age;
};

struct Son_IMPL {
    Class isa;
    int _age;
    double _height;
};

所以實(shí)例對象的本質(zhì)是結(jié)構(gòu)體楷力,(在c++文件中查找類名_IMPL就能找到這個(gè)結(jié)構(gòu)體)喊式,里面有一個(gè)isa指針和其他成員變量。所以實(shí)例對象在內(nèi)存中存儲(chǔ)的內(nèi)容是 isa指針 + 其他成員變量萧朝。

如下圖


22813661-930c9636126bc071.png

我們平時(shí)說打印出來的實(shí)例對象的地址開始就是指的是isa的地址岔留,即isa的地址排在最前面,就是我們實(shí)例對象的地址

2检柬、class-類對象

從第一部分我們了解到献联,實(shí)例對象只存儲(chǔ)isa指針和成員變量,那類里面的方法啊何址,屬性啊等等一些類信息存放在哪里里逆?為什么這些信息沒有存放在實(shí)例對象里?

因?yàn)閷?shí)例對象可能有很多個(gè)用爪,不可能每創(chuàng)建一個(gè)實(shí)例對象都存一份方法原押、屬性.....的。 這些只需要存一份就可以了偎血。一個(gè)類有且只有一個(gè)類對象诸衔。把屬性啊方法啊等信息存在類對象中也再合適不過了。

2.1 創(chuàng)建類對象
NSObject *obj = [[NSObject alloc] init];
Class objClass1 = [NSObject class];
Class objClass2 = [obj class];
Class objClass3 = object_getClass(obj);

我們可以打印一下颇玷,objClass1,objClass12,objClass13他們的內(nèi)存地址都是一樣的笨农。也驗(yàn)證了一個(gè)類有且一有一個(gè)類對象

2.2 類對象的本質(zhì)
7819764-55a4e660ba37ea51.png

如上我們可以看出,類對象中存放了
1亚隙、isa指針
2磁餐、super指針
3、類的屬性信息(@property)阿弃、類的對象方法信息(instance method)
4、類的協(xié)議信息(protocol)羞延、類的成員變量信息(ivar)
........

類對象里面也有一個(gè)isa指針渣淳,還有一個(gè)super指針,那他們分別指向哪里伴箩,又有什么作用呢入愧? 我們稍后就會(huì)講到。 當(dāng)然這里還有一個(gè)疑問嗤谚,既然類對象里面存放的是對象方法信息棺蛛,那類方法信息存放在哪里呢?

22813661-8d5f2056e0a8a28b.png

3巩步、meta-class-元類對象

構(gòu)建

 Class objectMetaClass = object_getClass([NSObject class]);

如上旁赊,objectMetaClass 就是 NSObject的元類對象,并且 每個(gè)類只有一個(gè)元類對象
元類對象和類對象的結(jié)構(gòu)是一樣的椅野,都是objc_class類型的結(jié)構(gòu)體终畅,元類對象存放類方法信息
1籍胯、isa指針
2、super指針
3离福、類的類方法信息(class method)
.........
meta-class對象和class對象的內(nèi)存結(jié)構(gòu)是一樣的杖狼,所以meta-class中也有類的屬性信息,類的對象方法信息等成員變量妖爷,但是其中的值可能是空的蝶涩。

22813661-771d3d0ee1491460.png

4、isa指針和super指針

實(shí)例對象絮识,類對象绿聘,元類對象中都有isa指針,類對象和元類對象中有super指針笋除。他們分別指向哪里斜友?

4.1、 實(shí)例對象的isa指針指向

eg1:子類Son中有一個(gè)實(shí)例方法- (void)sonTest 垃它,創(chuàng)建一個(gè)實(shí)例對象son鲜屏,然后用這個(gè)對象調(diào)用方法[son sonTest];。

類對象中存儲(chǔ)著實(shí)例方法信息国拇。當(dāng)實(shí)例對象調(diào)用實(shí)例方法時(shí)
實(shí)例方法存儲(chǔ)在類對象中洛史。實(shí)例對象調(diào)用實(shí)例方法時(shí),實(shí)例對象對象通過isa指針找到類對象酱吝,進(jìn)而找到類對象中相應(yīng)的實(shí)例方法進(jìn)行調(diào)用也殖。
實(shí)例對象的isa指針指向它的類對象。

4.2务热、類對象的isa指針指向

元類對象中存儲(chǔ)著類方法信息忆嗜。當(dāng)類對象調(diào)用類方法時(shí),類對象通過isa指針找到元類對象崎岂,進(jìn)而找到元類對象中相應(yīng)的類方法進(jìn)行調(diào)用捆毫,類對象的isa指針指向它的元類對象。

4.3冲甘、元類對象的isa指針指向

元類對象的isa指針指向基類的元類對象(eg:Son的元類對象和Father的元類對象都指向NSObject的元類對象)

4.4绩卤、類對象的super指針指向

eg4:父類Father中有一個(gè)實(shí)例方法- (void)fatherTest ,創(chuàng)建一個(gè)子類實(shí)例對象son江醇,然后用這個(gè)對象調(diào)用方法[son fatherTest];濒憋。

從4.1我們知道,son對象的isa指針會(huì)找到它的類對象陶夜,但是類對象中沒有fatherTest這個(gè)對象方法凛驮,所以類對象會(huì)通過它的super指針找到父類的類對象,而fatherTest這個(gè)方法是存放在Father的類對象中的律适,進(jìn)而調(diào)用辐烂。類對象的super指針是指向父類的類對象的遏插。
特例:當(dāng)這個(gè)類沒有父類時(shí)(基類),則指向nil

4.5纠修、元類對象的super指針指向

元類對象的super指針指向父類的元類對象
特例:基類的元類對象super指針指向基類的類對象

1853063-ab35405f00cf1bfc.png

總結(jié)如下

  • instance的isa指向class
  • class的isa指向meta-class
  • meta-class的isa指向基類的meta-class
  • class的superclass指向父類的class
    如果沒有父類胳嘲,superclass指針為nil
  • meta-class的superclass指向父類的meta-class
    基類的meta-class的superclass指向基類的class
  • instance調(diào)用對象方法的軌跡
    isa找到class,方法不存在扣草,就通過superclass找父類
  • class調(diào)用類方法的軌跡
    isa找meta-class了牛,方法不存在,就通過superclass找父類

二辰妙、通過object_getClass探究isa指針指向問題

介紹幾個(gè)函數(shù)

objc_getMetaClass(const char * _Nonnull name)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
object_getClass(id _Nullable obj) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
class_isMetaClass(Class _Nullable cls) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
- (Class)superclass
+ (Class)class
  • objc_getMetaClass用于獲取元類對象
  • class_isMetaClass用于判斷Class對象是否為元類
  • object_getClass用于獲取對象的isa指針指向的對象
  • -(Class)superclass 用于獲取對象的superclass指針?biāo)赶虻膶ο?/li>
  • +(Class)class 獲取類對象

1.有代碼如下:

    // EDStudent 繼承于 EDPerson 鹰祸,EDPerson 繼承于 NSObject
    NSObject *object1 = [[NSObject alloc] init]; // 基類 實(shí)例對象
    Class object2 = object_getClass(object1); // object1 的isa指針 所指向的對象
    Class object3 = object_getClass(object2); // object2 的isa指針 所指向的對象
    Class object4 = [NSObject class]; // 基類 類對象
    Class object5 = objc_getMetaClass("NSObject"); //基類 元類對象
    Class object6 = object_getClass(object5); // 元類對象的isa指針 所指向的對象
    NSLog(@"runtimeTest1 %p %p %p %p %p %p %d",object1,object2,object3,object4,object5,object6,class_isMetaClass(object3));

運(yùn)行結(jié)果如下:

runtimeTest1 0x60000311c410 0x7fff86b6c660 0x7fff86b6c638 0x7fff86b6c660 0x7fff86b6c638 0x7fff86b6c638 1

上文我們不難發(fā)現(xiàn),object2 和object4 的內(nèi)存地址是一樣的密浑,object3蛙婴、object5、object6的內(nèi)存地址是一樣的尔破,object4 是類對象街图,object5是元類對象~

也就是說基類的實(shí)例對象object1的isa指針是指向基類的類對象object2(object4),基類的類對象object2的isa指針是指向基類的元類對象object3(object5),基類的元類對象object5的isa指針指向基類的元類對象本身object6(object5)

2.有代碼如下

    // EDStudent 繼承于 EDPerson ,EDPerson 繼承于 NSObject
    EDPerson *p1 = [[EDPerson alloc] init]; // 實(shí)例對象
    Class p2 = object_getClass(p1); // p1 的isa指針 所指向的對象
    Class p3 = object_getClass(p2); // p2 的isa指針 所指向的對象
    Class p4 = [EDPerson class]; // 類對象
    Class p5 = objc_getMetaClass("EDPerson"); // 元類對象
    Class p6 = object_getClass(p5); // 元類對象p5的isa指針 所指向的對象
    Class objc = objc_getMetaClass("NSObject"); // 基類 元類對象
    NSLog(@"runtimeTest2 %p %p %p %p %p %p %p %d",p1,p2,p3,p4,p5,p6,objc,class_isMetaClass(p3));

運(yùn)行結(jié)果如下:

runtimeTest2 0x600003b339a0 0x1066168b0 0x106616888 0x1066168b0 0x106616888 0x7fff86b6c638 0x7fff86b6c638 1

上文我們不難發(fā)現(xiàn)懒构,p2和p4的內(nèi)存地址一樣餐济,p3和p5的內(nèi)存地址一樣,p6和objc內(nèi)存地址一樣胆剧,p4是類對象絮姆,p5是元類對象,objc是基類的元類對象

也就是說 實(shí)例對象的isa指針是指向類對象的秩霍,類對象的isa指針是指向元類對象的篙悯,元類對象的isa指針是指向基類的元類對象

綜上:
實(shí)例對象的isa指針是指向類對象,類對象的isa指針是指向元類對象铃绒,元類對象的isa指針都是指向基類的元類對象

3.有代碼如下

    // EDStudent 繼承于 EDPerson 辕近,EDPerson 繼承于 NSObject
    Class objc1 = [EDStudent class];  // EDStudent 類對象 objc1
    Class objc2 = [objc1 superclass]; // objc1 的 superclass指針 所指向的對象 (EDPerson 類對象) objc2
    Class objc3 = [objc2 superclass]; // objc2 的 superclass指針 所指向的對象 (NSObject 類對象) objc3
    Class objc4 = [objc3 superclass]; // objc3 的 superclass指針 所指向的對象 (nil) objc4
    
    Class objc5 = [EDPerson class]; // EDPerson 類對象 objc5
    Class objc6 = [NSObject class]; // NSObject 類對象 objc6
    
    NSLog(@"runtimeTest3 %p %p %p %p %p %p",objc1,objc2,objc3,objc4,objc5,objc6);

運(yùn)行結(jié)果如下:

runtimeTest3 0x102965950 0x102965900 0x7fff86b6c660 0x0 0x102965900 0x7fff86b6c660

上文我們不難發(fā)現(xiàn),objc2匿垄、objc5內(nèi)存地址一樣,objc3归粉、objc6內(nèi)存地址一樣椿疗,objc4是nil。objc5 是EDPerson類對象糠悼,objc6 是NSObject類對象届榄。

也就是說子類EDStudent的類對象的superclass指針是指向父類EDPerson的類對象,父類EDPerson的類對象的superclass指針是指向基類NSObject的類對象倔喂,基類NSObject的類對象的superclass指針是指向nil

4.有代碼如下

    // EDStudent 繼承于 EDPerson 铝条,EDPerson 繼承于 NSObject
    Class objc1 = objc_getMetaClass("EDStudent"); // EDStudent 元類對象 objc1
    Class objc2 = [objc1 superclass]; // objc1 的 superclass指針 所指向的對象 (EDPerson 元類對象)
    Class objc3 = [objc2 superclass]; // objc2 的 superclass指針 所指向的對象 (NSObject 元類對象)
    Class objc4 = [objc3 superclass]; // objc3 的 superclass指針 所指向的對象 (NSObject 類對象) 基類的元類對象的superclass指針是指向基類的類對象的
    
    Class objc5 = objc_getMetaClass("EDPerson"); // EDPerson 元類對象 objc5
    Class objc6 = objc_getMetaClass("NSObject"); // NSObject 元類對象 objc6
    Class objc7 = [NSObject class]; // NSObject 類對象 objc7
    
    NSLog(@"runtimeTest4 %p %p %p %p %p %p %p",objc1,objc2,objc3,objc4,objc5,objc6,objc7);

運(yùn)行結(jié)果如下:

runtimeTest4 0x102965928 0x1029658d8 0x7fff86b6c638 0x7fff86b6c660 0x1029658d8 0x7fff86b6c638 0x7fff86b6c660

上文不難發(fā)現(xiàn)靖苇,objc2、objc5內(nèi)存地址一樣班缰,objc3贤壁、objc6內(nèi)存地址一樣,objc4埠忘、objc7內(nèi)存地址一樣脾拆。objc5是EDPerson元類對象,objc6是NSObject元類對象莹妒,objc7是NSObject類對象

也就是說名船,子類EDStudent的元類對象的superclass指針是指向父類EDPerson的元類對象,父類EDPerson的元類對象的superclass指針指向基類NSObject的元類對象旨怠,基類的元類對象的superclass指針指向基類NSObject的類對象

綜上:
子類的類對象的superclass指針是指向父類的類對象渠驼,父類的類對象的superclass指針指向基類的類對象,基類的類對象的superclass指針是指向nil
子類的元類對象的superclass指針是指向父類的元類對象鉴腻,父類的元類對象的superclass指針是指向基類的元類對象迷扇,基類的元類對象的superclass指針是指向基類的類對象

三、實(shí)例方法和類方法的調(diào)用

有代碼如下:

@interface NSObject (runtime)
- (void)test;
+ (void)test;
@end

@implementation NSObject (runtime)
- (void)test{
    NSLog(@"NSObject 實(shí)例方法 Test 執(zhí)行");
}
+ (void)test{
    NSLog(@"NSObject 類方法 Test 執(zhí)行");
}
@end

@interface EDPerson : NSObject

@end

@implementation EDPerson
- (void)test {
    NSLog(@"EDPerson 實(shí)例方法 Test 執(zhí)行");
}
+ (void)test{
    NSLog(@"EDPerson 類方法 Test 執(zhí)行");
}
@end

@interface EDStudent : EDPerson

@end

@implementation EDStudent
- (void)test {
    NSLog(@"EDStudent 實(shí)例方法 Test 執(zhí)行");
}
+ (void)test{
    NSLog(@"EDStudent 類方法 Test 執(zhí)行");
}
@end

- (void)runtimeTest5 {
    [[EDStudent new] test];
    [EDStudent test];
}

當(dāng)前控制臺(tái)會(huì)打印“ EDStudent 實(shí)例方法 Test 執(zhí)行 ” 和 “EDStudent 類方法 Test 執(zhí)行”
如果注釋掉EDStudent類的- (void)test 和+ (void)test拘哨,控制臺(tái)會(huì)打印 “EDPerson 實(shí)例方法 Test 執(zhí)行”和“EDPerson 類方法 Test 執(zhí)行”
如果再注釋掉EDPerson類的- (void)test 和+ (void)test谋梭,控制臺(tái)會(huì)打印“NSObject 實(shí)例方法 Test 執(zhí)行” 和 “NSObject 類方法 Test 執(zhí)行”
如果此時(shí)再注釋掉NSObject類的+ (void)test,此時(shí)[EDStudent test] 并不會(huì)報(bào)錯(cuò)倦青,控制臺(tái)會(huì)打印“NSObject 實(shí)例方法 Test 執(zhí)行” 和 “NSObject 實(shí)例方法 Test 執(zhí)行”

綜上:
實(shí)例方法的調(diào)用軌跡:實(shí)例對象通過isa指針找到類對象瓮床,在類對象的方法列表中查找該方法,如果找不到产镐,就通過superclass指針繼續(xù)向上查找隘庄。
類方法的調(diào)用軌跡:類對象通過isa指針找到元類對象,在元類對象的方法列表中查找該方法癣亚,如果找不到丑掺,就通過superclass指針繼續(xù)向上查找。

四述雾、相關(guān)知識(shí)點(diǎn)

在蘋果開源代碼(https://opensource.apple.com/tarballs/)中下載objc4

1. class

代碼如下:

    Class objc1 = [EDStudent class];
    Class objc2 = [[EDStudent new] class];
    NSLog(@"runtimeTest6 %p %p",objc1,objc2);

運(yùn)行結(jié)果:

runtimeTest6 0x10ae388c0 0x10ae388c0

我們不難發(fā)現(xiàn)街州,objc1 和 objc2的內(nèi)存地址是一樣的
為什么呢,我們看下源碼

  • object_getClass
Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}

object_getClass 返回的是當(dāng)前對象的isa指針?biāo)赶虻膶ο?/strong>

  • class
+ (Class)class {
    return self;
}

- (Class)class {
    return object_getClass(self);
}

類方法class玻孟,是返回當(dāng)前類的類對象
實(shí)例方法class唆缴,也是返回當(dāng)前類的類對象。object_getClass(self),是獲取self的isa指針?biāo)赶虻膶ο笫螋幔鴖elf是當(dāng)前類的實(shí)例對象面徽,實(shí)例對象的isa指針是指向類對象,因而此時(shí)object_getClass(self)是獲取當(dāng)前類的對象的。

綜上
class方法是返回當(dāng)前類的類對象

2.superclass

代碼如下:

    Class objc1 = [EDStudent superclass];
    Class objc2 = [[EDStudent new] superclass];
    NSLog(@"runtimeTest7 %p %p",objc1,objc2);

運(yùn)行結(jié)果:

runtimeTest7 0x10ae38870 0x10ae38870

我們不難發(fā)現(xiàn)趟紊,objc1 和 objc2的內(nèi)存地址是一樣的氮双。
來我們繼續(xù)看源碼

  • superclass
+ (Class)superclass {
    return self->getSuperclass();
}

- (Class)superclass {
    return [self class]->getSuperclass();
}

類方法superclass的實(shí)質(zhì)是self->getSuperclass(),此時(shí)self是類對象霎匈,也就是說類方法superclass 返回的是當(dāng)前類的類對象的superclass指針?biāo)赶虻膶ο蟆?br> 實(shí)例方法superclass的實(shí)質(zhì)是[self class]->getSuperclass()戴差,此時(shí)self是實(shí)例對象,[self class]的實(shí)質(zhì)是object_getClass(self)唧躲,因而此時(shí)的[self class] 返回的是實(shí)例對象self的isa指針?biāo)赶虻膶ο笤焱欤串?dāng)前類的類對象,也就是說弄痹,實(shí)例方法superclass 返回的也是當(dāng)前類的類對象的superclass指針?biāo)赶虻膶ο蟆?/strong>

綜上
superclass 方法是返回當(dāng)前類的類對象的superclass指針?biāo)赶虻膶ο?/strong>

3.isKindOfClass 和 isMemberOfClass

代碼如下:

    BOOL res1 = [[EDStudent new] isKindOfClass:[EDStudent class]];
    BOOL res2 = [[EDStudent class] isKindOfClass:[EDStudent class]];
    BOOL res3 = [[NSObject class] isKindOfClass:[NSObject class]];
    NSLog(@"runtimeTest8 %d %d %d",res1,res2,res3);

運(yùn)行結(jié)果:

runtimeTest8 1 0 1

代碼如下:

    BOOL res1 = [[EDStudent new] isMemberOfClass:[EDStudent class]];
    BOOL res2 = [[EDStudent class] isMemberOfClass:[EDStudent class]];
    BOOL res3 = [[NSObject class] isMemberOfClass:[NSObject class]];
    NSLog(@"runtimeTest9 %d %d %d",res1,res2,res3);

運(yùn)行結(jié)果:

runtimeTest9 1 0 0

是不是和我們平時(shí)的認(rèn)知有些不一樣饭入,別急,想要理解為什么是這樣肛真,我們來看下源碼

  • isKindOfClass
+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = self->ISA(); tcls; tcls = tcls->getSuperclass()) {
        if (tcls == cls) return YES;
    }
    return NO;
}

- (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = [self class]; tcls; tcls = tcls->getSuperclass()) {
        if (tcls == cls) return YES;
    }
    return NO;
}

在源碼上谐丢,我們不難發(fā)現(xiàn),isKindOfClass的類方法和實(shí)例方法的區(qū)別在于for循環(huán)的初始值tcls蚓让,類方法isKindOfClass的for循環(huán)初始值是tcls = self->ISA()乾忱,初始值tcls是當(dāng)前對象的isa指針?biāo)赶虻膶ο螅瑢?shí)例方法isKindOfClass的for循環(huán)初始值是tcls = [self class],由于是實(shí)例方法历极,因而[self class]可以改寫為object_getClass(self)窄瘟,而object_getClass表示當(dāng)前對象的isa指針?biāo)赶虻膶ο?因而isKindOfClass的類方法和實(shí)例方法for循環(huán)的初始值tcls都是當(dāng)前對象的isa指針?biāo)赶虻膶ο?/strong>

綜上
isKindOfClass方法是一個(gè)for循環(huán)查找,由當(dāng)前對象的isa指針?biāo)赶虻膶ο螅╰cls = self->ISA() 或 tcls = [self class])開始趟卸,通過superclass指針(tcls = tcls->getSuperclass())向上查找蹄葱,如果找到的對象和cls相同就返回YES,否則返回NO

  • isMemberOfClass
+ (BOOL)isMemberOfClass:(Class)cls {
    return self->ISA() == cls;
}

- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}

和 isKindOfClass 類似锄列,實(shí)例方法isMemberOfClass 中的[self class] 可以改寫為object_getClass(self)图云,而object_getClass(self)表示當(dāng)前對象的isa指針?biāo)赶虻膶ο螅蚨鴖elf->ISA() 和 [self class] 都是表示當(dāng)前對象的isa指針?biāo)赶虻膶ο?/strong>

綜上
isMemberOfClass方法是判斷當(dāng)前對象的isa指針?biāo)赶虻膶ο蠛蚦ls是否相同

看到這邻邮,不知道大家有沒有一個(gè)小疑問竣况,當(dāng)前類的類對象,不管是通過何種方式獲取的筒严,它們的內(nèi)存地址都是一樣的丹泉,當(dāng)前類的元類對象,也是如此~

類對象保存的是創(chuàng)建實(shí)例對象所需要的信息(實(shí)例方法 協(xié)議等)鸭蛙,因而它只需要一份嘀掸,不一定是單例
元類對象保存的是創(chuàng)建類對象所需的信息(類方法),因而它也只需一份规惰,不一定是單例

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市泉蝌,隨后出現(xiàn)的幾起案子歇万,更是在濱河造成了極大的恐慌揩晴,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贪磺,死亡現(xiàn)場離奇詭異硫兰,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)寒锚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門劫映,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人刹前,你說我怎么就攤上這事泳赋。” “怎么了喇喉?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵祖今,是天一觀的道長。 經(jīng)常有香客問我拣技,道長千诬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任膏斤,我火速辦了婚禮徐绑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘莫辨。我一直安慰自己傲茄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布衔掸。 她就那樣靜靜地躺著烫幕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪敞映。 梳的紋絲不亂的頭發(fā)上较曼,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音振愿,去河邊找鬼捷犹。 笑死,一個(gè)胖子當(dāng)著我的面吹牛冕末,可吹牛的內(nèi)容都是我干的萍歉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼档桃,長吁一口氣:“原來是場噩夢啊……” “哼枪孩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蔑舞,失蹤者是張志新(化名)和其女友劉穎拒担,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體攻询,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡从撼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钧栖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片低零。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖拯杠,靈堂內(nèi)的尸體忽然破棺而出掏婶,到底是詐尸還是另有隱情,我是刑警寧澤阴挣,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布气堕,位于F島的核電站,受9級特大地震影響畔咧,放射性物質(zhì)發(fā)生泄漏茎芭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一誓沸、第九天 我趴在偏房一處隱蔽的房頂上張望梅桩。 院中可真熱鬧,春花似錦拜隧、人聲如沸宿百。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽垦页。三九已至,卻和暖如春干奢,著一層夾襖步出監(jiān)牢的瞬間痊焊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工忿峻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留薄啥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓逛尚,卻偏偏與公主長得像垄惧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子绰寞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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