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

你可能感兴趣的:(Runtime)