先来做几道题目,做的出来的就不要往下看了。
1 |
|
下面公布答案,答对的就撤了吧不要在这里浪费时间了,没答出来的那就跟着我一起一探究竟吧😁😀😃
1 | 1__0_1_1__0_0_1__0_0_ |
先打开objc来看看+ isMemberOfClass
,- isMemberOfClass
,+ isKindOfClass
,- isKindOfClass
,+ (Class)class
,- (Class)class
的实现,这些方法都是成对出现的,分别是对象方法和类方法。
分别解释一下各个方法,注意区分区别:
1 |
|
上面提到了isa,那么isa到底是个什么的东西呢 ?
直接xcode搜索NSObject可以看到
1 | @interface NSObject <NSObject> { |
再点进去看
1 |
|
可以得出结论
Class
就是指向objc_class
结构体的指针;id
就是指向objc_object
结构体的指针;
由类和对象的定义,我们可以看出,其成员变量中都含有isa指针,isa指向的是一个类,其指向该对象所属的类。我们可以把isa当作是一个对象的标志,因此类也是一个对象,我们称之为类对象,其isa指针,指向该类对象所属的类,我们称之为元类(metaClass)
isa指向的类可以通过【object class】 来获取,但是如果是类对象的话通过【class】来获取的话是本身而不是元类,这取决于上面提到的class的实现。我们可以通过object_getClass()来获取isa,适用于实例对象和类对象。
1 | Animal *animal = [[Animal alloc] init]; |
打印结果
1 |
|
可以得出下面一张图
由打印的结果以及上面的图可以得出以下结论:
- 实例对象的isa指向对象所属的类;
- 类对象的isa指向的是类对象所属的类,也就是元类;
- 元类对象的isa指向元类对象所属的类,也就是根元类;
- 根元类的isa指向本身。
好了有了上面的理解,我们再来一一解答之前的题目。
- BOOL isEqual = [p isKindOfClass:[Animal class]];
1 |
|
- BOOL isEqual1 = [Animal isKindOfClass:[Animal class]];
1 | 1. [Animal isKindOfClass],结合`+isKindOfClass`的定义,取得是Animal的isa,所以是Animl的元类; |
- BOOL isEqual2 = [NSObject isKindOfClass:[NSObject class]];
1 | 1. [NSObject class]取的是类NSObject ; |
- BOOL isEqual3 = [p isMemberOfClass:[Animal class]];
1 | 1. [Animal class] - > Animal; |
- BOOL isEqual4 = [Animal isMemberOfClass:[Animal class]];
1 | 1. [Animal class] - > Animal; |
- BOOL isEqual5 = [NSObject isMemberOfClass:[NSObject class]];
1 | 1. [NSObject class] - > NSObject; |
- BOOL isEqual6 = [(id)[NSObject class] isKindOfClass:[NSObject class]];
1 | 1. [NSObject class] - > NSObject; |
- BOOL isEqual7 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];
1 | 1. [NSObject class] - > NSObject; |
- BOOL isEqual8 = [(id)[Dog class] isKindOfClass:[Dog class]];
1 | 1. [Dog class] - > Dog |
- BOOL isEqual9 = [(id)[Dog class] isMemberOfClass:[Dog class]];
1 | 1. [Dog class] - > Dog |
相信到这里大家应该有个很好的认识了。
参考:
http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html