runtime方法 - class_addMethod
official document 官方文档
/**
* 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 _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, const char * _Nullable types) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
details that are easy to ignore 容易忽略的细节
- 这是一个 c 语言函数;
- 最后一个参数
const char * _Nullable types
, 官方解释为:An array of characters that describe the types of the arguments to the method
, 注意, 这里的method
指的同样是 c 语言函数, 不了解这一点, 一定有此疑问 - Objective-C 方法和An array of characters
中元素的个数不对应; - 同样,
imp
参数的注释 -A function which is the implementation of the new method. The function must take at least two arguments—self and _cmd
中,function
同样指的是 C 语言函数;
parameter analysis 参数解析
cls
: 添加方法的类对象, 获取方式为[<instance> class]
或者<instance>.class
;name
: 用来指定被添加方法名称的选择子, 类型为SEL
, 若方法名可以直接获取, 则等同于@selector(方法名称)
;imp
: c 语言函数指针, 类型为IMP
, 若函数在作用域内可以获取到, 则- (1) C语言写法: (IMP) 方法名;
- (2) OC写法: class_getMethodImplementation(self, @selector(方法名));
types
: 代表imp
函数返回值和参数的字符串, Type Encodings的详细用法可以参考官方文档, 强烈建议使用如下方法自动生成, 而不是暴力手打;?
/**
* Returns a string describing a method's parameter and return types.
*
* @param m The method to inspect.
*
* @return A C string. The string may be \c NULL.
*/
OBJC_EXPORT const char * _Nullable method_getTypeEncoding(Method _Nonnull m) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
吐槽 ?
如果最后一个参数没有特别的用法, 真的非常鸡肋, 感觉是闲得蛋疼, 不知道为什么要有这么个参数, 写这个方法的童鞋, 你粗来, 咱聊谈谈…