ios底层原理之isa、superClass

283 阅读3分钟

isa指针

  • instance的isa指向class
  • 当调用对象方法时,通过instance的isa找到class,最后找到对象方法进行调用
  • class的isa指向meta-class
  • 当调用类方法时,通过class的isa找到meta-class,最后找到类方法进行调用

class对象的superclass指针

  • Student继承于Person
  • 当Student的instance对象要调用Person的对象方法时,会通过isa找到Student的class,然后通过superclass找到Person的class,最后找到对象方法的实现进行调用
  • 类对象的superclass指向的是父类的类对象

meta-class对象的superclass指针

  • 元类对象的superclass指向的是父类的元类对象
  • 当Student的class要调用Person的类方法时,会先通过isa找到Student的meta-class,然后通过Superclass找到Person的meta-class,最后找到类方法进行调用

补充、总结

  • meta-class的isa指向基类(NSObject)的meta-class
  • class的superclass指向父类的class,如果没有父类,superclass指针为nil
  • meta-class的superclass指向父类的meta-class,基类的meta-class的superclass指向基类的class
  • instance调用对象方法:isa找到class,方法不存在,就通过superclass找父类的class
  • class调用类方法:isa找到meta-class,方法不存在,就通过superclass找父类的meta-class

isa细节

  • 从64bit开始,isa需要进行一次位运算,才能计算出真实地址
@interface Person : NSObject<NSCopying>
{
    @public
    int _age;
}
@property (nonatomic, assign) int no;
- (void)personInstanceMethod;
+ (void)personClassMethod;
@end

@implementation Person

- (void)personInstanceMethod{
    
}

+ (void)personClassMethod{
    
}

- (id)copyWithZone:(NSZone *)zone{
    return nil;
}

@end

@interface Student : Person<NSCoding>
{
    @public
    int _weight;
}
@property (nonatomic, assign) int height;
- (void)studentInstanceMethod;
+ (void)studentClassMethod;
@end

@implementation Student
- (void)studentInstanceMethod{
    
}

+ (void)studentClassMethod{
    
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    
}

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
    return nil;
}
@end

struct mj_objc_class{
    Class isa;
};

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        
        //person->isa:0x001d800100001499
        Person *person = [[Person alloc] init];
        
        //personClass:0x0000000100001498
        //0x001d800100001499 & 0x00007ffffffffff8(ISA_MASK) = 0x0000000100001498
        //得出结论:isa&ISA_MASK 才是下一个isa
        Class personClass = [Person class];
        
        //personMetaClass 0x0000000100001470
        Class personMetaClass = object_getClass(personClass);
        //personClass -> isa = 0x001d800100001471
        //0x001d800100001471 & 0x00007ffffffffff8(ISA_MASK) = 0x0000000100001470
        //得出结论:isa&ISA_MASK 才是下一个isa
        struct mj_objc_class *personClass2 = (__bridge struct mj_objc_class *)(personClass);
        
        NSLog(@"%p %p %p",person,personClass,personMetaClass);
    }
    return 0;
}

  • 类对象的superclass指向的是父类的类对象,不需要进行位运算

class和meta-class的结构

对象的isa指针指向哪里?

  • instance对象的isa指向class对象
  • class对象的isa指向meta-class对象
  • meta-class对象的isa指向基类的meta-class对象

OC的类信息存放在哪里?

  • 对象方法、属性、成员变量、协议信息,存放在class对象中
  • 类方法,存取在meta-class对象中
  • 成员变量的具体值,存放在instance对象