runtime 运行时

了解oc 运行时可分为以下三块:
1.概念 IMP SEL MEthod
2.消息发送流程
3.消息转发流程

概念篇:

SEL:oc在编译时会根据方法名和参数序列生成唯一的方法标识就是SEL
IMP: SEL 对应方法实现
MEthod:在 SEL 和 IMP之间建立映射

消息发送流程:

//第一个参数消息接收者,第二个参数 SEL
OBJC_EXPORT void objc_msgSend(void  id self, SEL op, ...  )

消息发送到对象时,会根据接收者对象所属类的isa指针在类的cache和methodList找到对应方法的实现,如果没找到就向其父类找,直到NSObject,如果还是没有找到就进入消息转发流程

消息转发流程:

1)动态方法解析:用来给一个类动态添加没有声明和实现的方法

//动态方法解析
+(BOOL)resolveInstanceMethod:(SEL)sel{
    NSString *selName = NSStringFromSelector(sel);
    if ([selName isEqualToString:@"eat"]) {
        class_addMethod(self, sel, (IMP)eat, "V@:");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
    objc_msgSend()
}

void eat(){
    NSLog(@"-----------------i am eating----------------");
}

2)上一步没有处理运行时调用备用接收者方法:

/*备用接收者,上一步没有处理时runtime会调用该方法 */
//这种方法属于单纯的转发,无法对消息的参数和返回值进行处理
-(id)forwardingTargetForSelector:(SEL)aSelector{
    NSString *selName = NSStringFromSelector(aSelector);
    if ([selName isEqualToString:@"eat"]) {
        return [[Children alloc] init];
    }
    return [super forwardingTargetForSelector:aSelector];
}

3)前两步都没有处理,进入消息完整转发流程

 /*  为了完整转发,需要重写以下方法 */
//消息转发机制为了创建NSInvocation需要使用这个方法获取信息,重写他为了指定方法签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
    NSString *selName = NSStringFromSelector(aSelector);
    if ([selName isEqualToString:@"testMethod"]) {
        return [NSMethodSignature signatureWithObjCTypes:"V@:"];
    }
    return [super methodSignatureForSelector:aSelector];
}
//对象需要创建一个NSInvocation对象,把消息调用的全部细节封装进去,包括selector,target,arguments等参数,还能够对返回结果进行处理
//NSInvocation对象可以做很多处理。比如修改实现方法,修改响应对象
- (void)forwardInvocation:(NSInvocation *)anInvocation{
    //改变响应方法
    [anInvocation setSelector:@selector(newMethodTest)];
    //改变响应对象
    [anInvocation invokeWithTarget:[Children new]];
}

//方法参数类型
enum _NSObjCValueType {
    NSObjCNoType = 0,
    NSObjCVoidType = 'v',
    NSObjCCharType = 'c',
    NSObjCShortType = 's',
    NSObjCLongType = 'l',
    NSObjCLonglongType = 'q',
    NSObjCFloatType = 'f',
    NSObjCDoubleType = 'd',
    NSObjCBoolType = 'B',
    NSObjCSelectorType = ':',
    NSObjCObjectType = '@',
    NSObjCStructType = '{',
    NSObjCPointerType = '^',
    NSObjCStringType = '*',
    NSObjCArrayType = '[',
    NSObjCUnionType = '(',
    NSObjCBitfield = 'b'
} NS_DEPRECATED(10_0, 10_5, 2_0, 2_0);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值