OC-RunTime运行时技术的总结具体代码实现

RunTime简称运行时。就是系统在运行的时候的一些机制,其中最主要的是消息机制。对于C语言,函数的调用在编译的时候会决定调用哪个函数( C语言的函数调用请看这里 )。编译完成之后直接顺序执行,无任何二义性。OC的函数调用成为消息发送。属于动态调用过程。在编译的时候并不能决定真正调用哪个函数(事实证明,在编 译阶段,OC可以调用任何函数,即使这个函数并未实现,只要申明过就不会报错。而C语言在编译阶段就会报错)。只有在真正运行的时候才会根据函数的名称找 到对应的函数来调用。
下面主要来介绍下RunTime库所用到的几个函数:
+ (BOOL)resolveInstanceMethod:(SEL)sel
解释:这个函数在运行时(runtime),没有找到SEL的IML时就会执行。这个函数是给类利用class_addMethod添加函数的机会。具体实现如下:
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    NSLog(@"2==%s %@",__func__,NSStringFromSelector(sel));

        //动态添加一个方法
            if(sel == @selector(run))
            {
                class_addMethod(self, sel, (IMP)Run, "v@:");
                return YES;
            }

    return [super resolveInstanceMethod:sel];
}
根据文档,如果实现了添加函数代码则返回YES,未实现返回NO。

+ (BOOL)resolveClassMethod:(SEL)sel

-(id)forwardingTargetForSelector:(SEL)aSelector
解释:流程到了这里,系统给了个将这个SEL转给其他对象的机会。
返回参数是一个对象,如果这个对象非nil、非self的话,系统会将运行的消息转发给这个对象执行。否则,继续查找其他流程。

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
-解释:这个函数和后面的forwardInvocation:是最后一个寻找IML的机会。这个函数让重载方有机会抛出一个函数的签名,再由后面的forwardInvocation:去执行。

- (void)forwardInvocation:(NSInvocation *)anInvocation
解释:真正执行从methodSignatureForSelector:返回的NSMethodSignature。在这个函数里可以将NSInvocation多次转发到多个对象中,这也是这种方式灵活的地方。(forwardingTargetForSelector只能以Selector的形式转向一个对象)

主要代码:

#import "Person.h"

@implementation Person
//-(void)Run{
//    NSLog(@"xascdvdv");
//}

void Run(id self, SEL sel)
{
    NSLog(@"1==%@ %s 2",self, sel_getName(sel));
}

+ (BOOL)resolveInstanceMethod:(SEL)sel
{
    NSLog(@"2==%s %@",__func__,NSStringFromSelector(sel));

        //动态添加一个方法
            if(sel == @selector(run))
            {
                class_addMethod(self, sel, (IMP)Run, "v@:");
                return YES;
            }

    return [super resolveInstanceMethod:sel];
}

    //当类的方法不存在时调用
+ (BOOL)resolveClassMethod:(SEL)sel
{
    NSLog(@"3===%s",__func__);

    return [super resolveClassMethod:sel];
}
-(id)forwardingTargetForSelector:(SEL)aSelector
{
    NSLog(@"4==%s %@",__func__,NSStringFromSelector(aSelector));

        //转发给Animal的实例,调用Animal的Run方法,如果不转发则跳到Step 3
        //    return [Animal new];

    return [super forwardingTargetForSelector:aSelector];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    NSLog(@"5==%s %@",__func__,NSStringFromSelector(aSelector));

    if(aSelector == @selector(Run))
        {
        return [NSMethodSignature signatureWithObjCTypes:"v@:"];
        }

    return [super methodSignatureForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    NSLog(@"6==%s",__func__);

    SEL selector=[anInvocation selector];
    Animal *animal=[Animal new];

    if([animal respondsToSelector:selector])
        {
        [anInvocation invokeWithTarget:animal];
        }
}

运行结果:
这里写图片描述
代码Demo地址:http://pan.baidu.com/s/1bl8iCY
参考文章:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008048

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图解AI

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值