class和superClass
class和superclass在NSObject.mm源码中的实现
+ (Class)class {
return self;
}
- (Class)class {
return object_getClass(self);
}
+ (Class)superclass {
return self->superclass;
}
- (Class)superclass {
return [self class]->superclass;
}
从源码中可以分析出:
- 实例对象的
- (Class)class方法,返回的是类对象 - 类对象的
+ (Class)class方法,返回的是类对象本身 - 实例对象的
- (Class)superclass方法,返回的是父类的类对象 - 类对象的
+ (Class)superclass方法,返回的也是父类的类对象
举例
创建两个类:Person和Student
@interface Person : NSObject
@end
//------------------------------
@interface Student : Person
@end
Student *stu = [[Student alloc] init];
// ===== class =====
// 结果都打印1 因为[stu class]和[Student class]返回的都是Student类对象
NSLog(@"%d", [stu class] == [Student class]);
NSLog(@"%d", [Student class] == [Student class]);
// 结果打印0 因为Student类对象 不等于 Person类对象
NSLog(@"%d", [Student class] == [Person class]);
// ===== superClass =====
// 结果打印0 stu的superClass返回的是父类Person类对象,所以不相等
NSLog(@"%d", [stu superclass] == [Student class]);
// 结果打印1
NSLog(@"%d", [stu superclass] == [Person class]);
// 结果打印0 Student的superClass返回的是父类Person的类对象,所以不相等
NSLog(@"%d", [Student superclass] == [Student class]);
// 结果打印1
NSLog(@"%d", [Student superclass] == [Person class]);
isMemberOfClass和isKindOfClass
NSObject.mm源码如下:
+ (BOOL)isMemberOfClass:(Class)cls {
return self->ISA() == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
从源码中可以分析出:
- 实例对象的
- (BOOL)isMemberOfClass:(Class)cls方法,比较的是当前类的类对象和传入类的类对象是否相等 - 实例对象的
- (BOOL)isKindOfClass:(Class)cls方法,比较的是当前类的类对象和传入类的类对象是否相等,如果不相等,则往上比较父类类对象和传入类对象是否相等 - 类对象的
+ (BOOL)isMemberOfClass:(Class)cls方法,比较的是当前类的元类和传入的类对象是否相等 (元类也是类对象的一种) - 类对象的
+ (BOOL)isKindOfClass:(Class)cls方法,比较的是当前类的元类和传入的类对象是否相等,如果不相等,则网上比较父类的元类对象和传入类对象是否相等
所以本质上,实例方法比较的是类对象是否相等;类方法比较的是元类对象是否相等
举例
// ===== 实例方法 =====
// 结果都为1 [Student class] 方法返回的是Student类对象,所以比较相等
NSLog(@"%d", [stu isMemberOfClass:[Student class]]);
NSLog(@"%d", [stu isKindOfClass:[Student class]]);
// 结果为0 这里isMemberOfClass比较的是Student类对象和Person类对象,所以不相等
NSLog(@"%d", [stu isMemberOfClass:[Person class]]);
// 结果为1 isKindOfClass先比较Student类对象和Person类对象是否相等,
// 不相等,所以找到Student的父类类对象Person,比较相等所以结果为1
NSLog(@"%d", [stu isKindOfClass:[Person class]]);
// ===== 类方法 =====
// 结果都为0 因为类方法比较的是元类对象,[Student class] 返回的是类对象,所以不相等
NSLog(@"%d", [Student isMemberOfClass:[Student class]]);
NSLog(@"%d", [Student isKindOfClass:[Student class]]);
// 结果都为1 因为object_getClass([Student class])方法返回的是Student的元类对象
NSLog(@"%d", [Student isMemberOfClass:object_getClass([Student class])]);
NSLog(@"%d", [Student isKindOfClass:object_getClass([Student class])]);
// 结果也是1 当前类的元类对象不等于传入类对象时,会往上比较父类的元类对象是否等于当前元类对象
NSLog(@"%d", [Student isKindOfClass:object_getClass([Person class])]);
// 特别注意,以下结果也是1,因为NSObject的元类对象的父类是NSObject类对象
NSLog(@"%d", [Student isKindOfClass:[NSObject class]]);
**说明: 以下两种方式本质上是一样的 **
因为Student调用类方法,使用的是类对象调用类方法
[Student class]返回的是类对象本身,所以本身也是类对象调用类方法
[Student isKindOfClass:[Student class]];[[Student class] isKindOfClass:[Student class]];
注意:
NSObject的元类对象的父类是NSObject类对象,所以任意继承自NSObject类的类对象调用
[xxx isKindOfClass:[NSObject class]],结果都为1