美文网首页
oc 函数传递机制,崩溃处理

oc 函数传递机制,崩溃处理

作者: ZKylh | 来源:发表于2017-03-10 19:52 被阅读0次

    /**

    总结:

    在一个函数找不到时,OC提供了三种方式去补救:

    1、调用resolveInstanceMethod给个机会让类添加动态添加方法去实现这个函数

    2、调用forwardingTargetForSelector让别的对象去执行这个函数

    3、调用forwardInvocation(函数执行器)灵活的将目标函数以其他形式执行。用methodSignatureForSelector先偷换方法的签名

    如果都不中,调用doesNotRecognizeSelector抛出异常。

    */

    #import"ViewController.h"

    #import"Person.h"

    #import"NSObject+Runtime.h"

    @interfaceViewController()

    @property(nonatomic,strong)Person*person;

    @end

    @implementationViewController

    - (void)viewDidLoad {

    [superviewDidLoad];

    _person= [Personalloc];

    [_personperformSelector:@selector(shaleba)];

    }

    @end

    #import"Person.h"

    #import

    @implementationPerson

    #pragma mark - crush最先调用,可以在这里用运行时交换方法

    +(BOOL)resolveInstanceMethod:(SEL)sel{

    if(sel ==@selector(shaleba)) {

    class_addMethod([selfclass],sel,class_getMethodImplementation(self,@selector(startEngine)),"@@:");

    returnNO;

    }

    return[superresolveInstanceMethod:sel];

    }

    //上面👆替换的方法

    - (void)startEngine {

    NSLog(@"我执行后就不会再崩溃了");

    }

    #pragma mark - crush第二调用,可以在这里直接指定一个对象去调用

    -(id)forwardingTargetForSelector:(SEL)aSelector{

    self.stu= [studentnew];

    returnself.stu;

    }

    #pragma mark - crush第3接锅侠之一这个是和下面方法一起使用的,可以在这里直接指定一个对象去调用

    -(NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector{

    self.stu= [studentnew];

    NSMethodSignature*signature =nil;

    //如果自己变身的类有改方法,则偷取出方法的签名

    if([self.stumethodSignatureForSelector:aSelector]) {

    //OC所有的底层方法至少有两个参数第一个参数方法的对象self第二个参数:方法的自身我们人工手写的方法参数是从第三个开始

    signature = [self.stumethodSignatureForSelector:aSelector];

    }

    else{

    signature = [supermethodSignatureForSelector:aSelector];

    }

    returnsignature;

    }

    #pragma mark - crush第3接锅侠之一这个是和下面方法一起使用的,可以在这里直接指定一个对象去调用

    //2.再检查方法的实现(调用方法)

    - (void)forwardInvocation:(NSInvocation*)invocation{

    //设置方法的执行者为自己copy的哪一个类,必须设置不然不会调用此方法

    [invocationsetTarget:self.stu];

    //动态拦截参数,修改参数

    if([self.stuisKindOfClass:NSClassFromString(@"Teacher")]) {

    //argument:参数的地址index:参数的下标

    NSString*s =@"呵呵,被改了";

    [invocationsetArgument:&satIndex:2];

    }

    //让自己的替身类去调用方法

    [invocationinvoke];

    }

    @end

    相关文章

      网友评论

          本文标题:oc 函数传递机制,崩溃处理

          本文链接:https://www.haomeiwen.com/subject/bsyogttx.html