runtime---实例对象、类对象与元类对象&消息传递&消息转发

类对象与元类对象的区别和联系

  • 类对象存储的是实例方法列表,元类对象存储的是类方法列表
  • 实例对象是objc_object结构,其中的isa指针指向其类对象,类对象是objc_class结构,objc_class是继承自objc_object结构,因此也有isa指针,其isa指针指向其元类对象,从而可以访问类方法
  • 类对象和元类对象都是objc_class数据结构的
  • 元类对象的isa指针都指向根元类对象,包括根元类对象自身
  • 根元类对象的superclass指针,指向的是根类对象
  • 根类对象的superclass指针,指向nil

当调用的类方法没有时,但是有同名的实例方法存在,那么会不会导致崩溃?

  • 不会崩溃,当调用类方法时,会依次调用元类对象中的类方法列表,直至找到根元类对象的类方法列表,但是仍然没有找到时,会根据元类对象的superclass指针指向的根类对象的方法列表中去找同名的实例方法列表

消息传递流程


NS_ASSUME_NONNULL_BEGIN

@interface Mobile : NSObject

@end

NS_ASSUME_NONNULL_END


#import "Mobile.h"

@implementation Mobile

@end
#import "Mobile.h"

NS_ASSUME_NONNULL_BEGIN

@interface Phone : Mobile

@end

NS_ASSUME_NONNULL_END

#import "Phone.h"

@implementation Phone
- (instancetype)init {
    self = [super init];
    if (self) {
        NSLog(@"%@",NSStringFromClass([self class])); //self isa指向类对象Phone ->NSObject类对象方法列表
        NSLog(@"%@",NSStringFromClass([super class])); //super isa指向类对象
    }
    return self;
}
@end

  • [self class]根据phone实例的isa指针,找到类对象,在类对象的缓存方法列表或实例方法列表中去寻找class这个方法
  • 本身是没有的,然后通过类对象中的superclass指针向其父类mobile中去寻找方法
  • mobile类中也是没有的,顺次查到,直至知道根类对象NSObject,有该方法的实现,调用这个方法的实现,最终返回给接收者receiver,即phone实例对象,打印结果为:Phone
  • [super class]会调用msgsendSuper这个函数,会从Phone类的父类对象方法列表中去查找,其中第一个固定参数是结构体objc_super,该结构体中有一个 id receiver成员,接收者仍然是Phone的实例对象,因此最终打印结果也为:Phone
runtime---实例对象、类对象与元类对象&消息传递&消息转发_第1张图片
消息传递流程图.png

消息传递--缓存查找流程

  • 通过给定的方法选择器SEL,作为key,通过hash算法,及通过一个hash函数cache_key_t来获取到对应的bucket_t结构在cache_t中的位置索引,从而获取到bucket_t,最终获取到bucket_t中的IMP函数指针
    f(key) = key & mask

消息传递--当前类对象中的查找流程

  • 在当前类对象的方法列表中,对于已排序好的列表,采用二分查找算法查找方法对应执行函数
  • 对于没有排序好的列表,采用一般遍历查找方法对应执行函数

消息传递--父类逐级查找流程

  • 通过当前类对象的superclass指针逐级向父类查找,判断父类是否为空,如果为空则结束

消息转发流程

  • 对于实例方法的转发流程


    runtime---实例对象、类对象与元类对象&消息传递&消息转发_第2张图片
    消息转发流程.png
#import 

NS_ASSUME_NONNULL_BEGIN

@interface RuntimeObject : NSObject

- (void)test;

@end

NS_ASSUME_NONNULL_END


#import "RuntimeObject.h"

@implementation RuntimeObject

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if (sel == @selector(test)) {
        return NO;
    }else {
        return [super resolveInstanceMethod:sel];
    }
}

- (id)forwardingTargetForSelector:(SEL)aSelector {
    return nil;
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    
    if (aSelector == @selector(test)) {
        return [NSMethodSignature signatureWithObjCTypes:"v@:"];
    }else {
        return [super methodSignatureForSelector:aSelector];
    }
}

- (void)forwardInvocation:(NSInvocation *)anInvocation {
    
}
@end

你可能感兴趣的:(runtime---实例对象、类对象与元类对象&消息传递&消息转发)