美文网首页runtime
2018之iOS class_addMethod使用

2018之iOS class_addMethod使用

作者: YYT1992 | 来源:发表于2018-03-06 14:30 被阅读660次

    前言

    近期项目不急,有时间看一些自己想看的东西。记得面试的时候都是在问runtimer的知识点,自己虽然知道一点这里面的知识点,但是很零碎。所以在这几天好好的研究一下。其实我也问过一个做sdk的朋友,他也说基本上平时开发用的不是很多。做sdk的用的比较多,因为要获取开发人员的某些属性,或者在不知道开发人员的类的结构下添加方法等。本次说class_addMethod 这个很有用的方法,感觉他就是一个作弊器。

    正文

    /** 
     * Adds a new method to a class with a given name and implementation.
     * 
     * @param cls The class to which to add a method.
     * @param name A selector that specifies the name of the method being added.
     * @param imp A function which is the implementation of the new method. The function must take at least two arguments—self and _cmd.
     * @param types An array of characters that describe the types of the arguments to the method. 
     * 
     * @return YES if the method was added successfully, otherwise NO 
     *  (for example, the class already contains a method implementation with that name).
     *
     * @note class_addMethod will add an override of a superclass's implementation, 
     *  but will not replace an existing implementation in this class. 
     *  To change an existing implementation, use method_setImplementation.
     */
    OBJC_EXPORT BOOL class_addMethod(Class cls, SEL name, IMP imp, 
                                     const char *types) 
         __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
    

    这个是API文档的解释,基本就是说这可以加入新的方法到一个类里面,然后介绍这里面几个参数的作用之类的。我感觉无论什么都要自己亲身实践才行,所以直接先上代码:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
       //动态添加一个方法
        Person *p = [[Person alloc]init];
        class_addMethod([Person class], @selector(printPerson), class_getMethodImplementation([ViewController class], @selector(find)), "v@:");
        [p performSelector:@selector(printPerson)];
    }
    
    

    非常简单的代码片段,我有一个Person类,现在我要在运行的时候给他增加一个方法,并且调用这个方法。

     class_addMethod(Class cls, SEL name, IMP imp, 
                                     const char *types)
    

    首先我们看看这个方法里面的参数:
    Class cos:我们需要一个class,比如我的[Person class]。
    SEL name:这个很有意思,这个名字自己可以随意想,就是添加的方法在本类里面叫做的名字,但是方法的格式一定要和你需要添加的方法的格式一样,比如有无参数。
    IMP imp:IMP就是Implementation的缩写,它是指向一个方法实现的指针,每一个方法都有一个对应的IMP。这里需要的是IMP,所以你不能直接写方法,需要用到一个方法:

    OBJC_EXPORT IMP class_getMethodImplementation(Class cls, SEL name) 
         __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
    

    这个方法也是runtime的方法,就是获得对应的方法的指针,也就是IMP。
    const char *types:这一个也很有意思,我刚开始也很费解,结果看了好多人的解释我释然了,知道吗,我释然啦,����。这个东西其实也很好理解:
    比如:”v@:”意思就是这已是一个void类型的方法,没有参数传入。
    再比如 “i@:”就是说这是一个int类型的方法,没有参数传入。
    再再比如”i@:@”就是说这是一个int类型的方法,又一个参数传入。
    好了,参数解释完了,还有一点需要注意,用这个方法添加的方法是无法直接调用的,必须用performSelector:调用。为甚么呢???
    因为performSelector是运行时系统负责去找方法的,在编译时候不做任何校验;如果直接调用编译是会自动校验。
    知道为甚么了吧,你添加方法是在运行时添加的,你在编译的时候还没有这个本类方法,所以当然不行啦。

    结束

    啦啦啦,结束啦,代码示例在此,如果您觉得还可以,给个✨✨吧。

    转自:http://blog.csdn.net/github_30943901/article/details/51210346

    相关文章

      网友评论

        本文标题:2018之iOS class_addMethod使用

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