iOS笔记系列目录
一 Code
- (void)testClassISA {
id b1 = [NSObject class];
id b2 = [NSObject class];
id b3 = [[NSObject new] class];
NSLog(@"[NSObject class] = %@ , %@, %@", b1,b2,b3);
// true
BOOL res1 = [(id)[NSObject class] isKindOfClass:(id)[NSObject class]];
// false
BOOL res2 = [(id)[NSObject class] isMemberOfClass:(id)[NSObject class]];
// true
BOOL res3 = [(id)[[NSObject new] class] isKindOfClass:(id)[NSObject class]];
// false
BOOL res4 = [(id)[[NSObject new] class] isMemberOfClass:(id)[NSObject class]];
// true
BOOL res5 = [(id)[[NSObject new] class] isKindOfClass:(id)[NSObject class]];
// true
BOOL res6 = [(id)[[NSObject new] class] isMemberOfClass:(id)[NSObject class]];
// false
BOOL res7 = [(id)[Test class] isKindOfClass:(id)[Test class]];
// false
BOOL res8 = [(id)[Test class] isKindOfClass:(id)[Test class]];
// false
BOOL res9 = [(id)[[Test new] class] isKindOfClass:(id)[Test class]];
// false
BOOL res10 = [(id)[[Test new] class] isMemberOfClass:(id)[Test class]];
// true
BOOL res11 = [(id)[Test new] isKindOfClass:(id)[Test class]];
// true
BOOL res12 = [(id)[Test new] isMemberOfClass:(id)[Test class]];
// 1, 0, 1, 0, 1, 1
NSLog(@"%d, %d, %d, %d, %d, %d",res1, res2, res3,res4,res5, res6);
// 0, 0, 0, 0, 1, 1
NSLog(@"%d, %d, %d, %d, %d, %d",res7, res8, res9,res10,res11, res12);
}
二 源码
0.源码解析
/// 类办法,返回本身
+ (Class)class {
return self;
}
/// 实例办法,查找isa(类)
- (Class)class {
return object_getClass(self);
}
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
inline Class
objc_object::getIsa()
{
if (isTaggedPointer()) {
uintptr_t slot = ((uintptr_t)this >> TAG_SLOT_SHIFT) & TAG_SLOT_MASK;
return objc_tag_classes[slot];
}
return ISA();
}
inline Class
objc_object::ISA()
{
assert(!isTaggedPointer());
return (Class)(isa.bits & ISA_MASK);
}
/// 类办法,沿着继承链,去断定isa(类对象isa是元类)和参数是否相等
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
/// 实例办法,沿着继承链,去断定isa(实例对象isa是类)和参数是否相等
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
/// 类办法,断定isa(元类)和参数是否相等
+ (BOOL)isMemberOfClass:(Class)cls {
return self->ISA() == cls;
}
/// 实例办法,断定isa(类)和参数是否相等
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
总结:
-
object_getClass(obj)
返回的是obj的isa指针;
-
[obj class]
则分两种状况:
- obj为实例对象
调用的是实例办法:- (Class)class
,返回的obj对象中的isa指针;
- obj为类对象(包含元类和根类以及根元类)
调用的是类办法:+ (Class)class
,返回的后果为其自身。
参考:【iOS笔记 #3】class办法和objc_getClass办法
1.isKindOfClass
是否是以后类或以后类的子类实例
Returns a Boolean value that indicates whether the receiver is an instance of given class or an instance of any class that inherits from that class.
断定根据
实例对象调用isKindOfClass
沿继承链获取isa(类对象),断定class与继承链上获取的isa是否有相等的
类对象调用isKindOfClass
沿继承链获取isa(元类对象),断定class与继承链上获取的isa是否有相等的
2.isMemberOfClass
是否是给定类的实例
Returns a Boolean value that indicates whether the receiver is an instance of a given class.
isMemberOfClass的源码实现是拿到本人的isa指针和本人比拟,是否相等。
三 解析
1. res1
BOOL res1 = [(id)[NSObject class] isKindOfClass:(id)[NSObject class]]; // true
[NSObject class]
类对象调用+(Class)class
返回本身,即NSObject
/// 类办法,沿着继承链,去断定isa(类对象isa是元类)和参数是否相等
+ (BOOL)isKindOfClass:(Class)cls;
返回本身,即NSObject的isa是NSObjectMeta,不等,沿继承链查找superclass,[NSObjectMeta superclass] == NSObject(图右上角可看出),此时相等,返回true
2. res2
BOOL res2 = [(id)[NSObject class] isMemberOfClass:(id)[NSObject class]]; // false
[NSObject class]
即NSObject
/// 类办法,断定isa(元类)和参数是否相等
+ (BOOL)isMemberOfClass:(Class)cls;
[NSObject class]的isa是NSObjectMeta,即NSObject != NSObjectMeta,即NSObject,所以是false
3. res3
BOOL res3 = [(id)[[NSObject new] class] isKindOfClass:(id)[NSObject class]]; // true
[NSObject new] class] == NSObject,后续剖析与res1统一,所以是true
4. res4
BOOL res4 = [(id)[[NSObject new] class] isMemberOfClass:(id)[NSObject class]]; // false
[NSObject new] class] == NSObject,后续剖析与res2统一,所以是false
5. res5
BOOL res5 = [(id)[NSObject new] isKindOfClass:(id)[NSObject class]]; // true
/// 实例办法,沿着继承链,去断定isa(实例对象isa是类)和参数是否相等
- (BOOL)isKindOfClass:(Class)cls;
id o = [NSObject new]; o 的calss是NSObject,[NSObject class] == NSObject,进入循环即相等,所以是true
6. res6
BOOL res6 = [(id)[NSObject new] isMemberOfClass:(id)[NSObject class]]; // true
/// 实例办法,断定isa(类)和参数是否相等
- (BOOL)isMemberOfClass:(Class)cls;
id o = [NSObject new]; o 的isa是NSObject,[NSObject class] == NSObject,进入循环即相等,所以是true
7. res7
BOOL res7 = [(id)[Test class] isKindOfClass:(id)[Test class]]; // false
[Test class] == Test
/// 类办法,沿着继承链,去断定isa(类对象isa是元类)和参数是否相等
+ (BOOL)isKindOfClass:(Class)cls;
1 -> Test的isa是TestMeta,TestMeta != Test;
2 -> 找superclass,[Test superclass] == NSObject,NSObject的isa是NSObjectMeta,NSObjectMeta != Test;
3 -> 持续找superclass,[NSObject superclass] == nil,nil != Test,所以是false
8. res8
BOOL res8 = [(id)[[Test new] class] isKindOfClass:(id)[Test class]]; // false
[Test class] == Test,[Test new] class] == Test
/// 类办法,沿着继承链,去断定isa(类对象isa是元类)和参数是否相等
+ (BOOL)isKindOfClass:(Class)cls;
1 -> Test 的isa是TestMeta,不等于Test,
2 -> Test的superclass是NSObject,NSObject的isa是NSObjectMeat,不等于Test,
3 -> NSObject的superclass是nil,不等于Test,所以是false
余下剖析同理……
发表回复