IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> iOS-Runtime之class_addMethod给类动态添加方法 -> 正文阅读

[移动开发]iOS-Runtime之class_addMethod给类动态添加方法

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 _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, 
                const char * _Nullable types) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

描述就是:给一个类添加一个新的方法和该方法的具体实现

BOOL: 返回值,YES:方法添加成功 ;NO:方法添加失败

参数:

1、Class cls

cls :要添加新方法的那个类;

传的类型 [类名 ?class]

实例方法,传入CLass;类方法,传入MetaClss;可以这样理解,OC里的Class里的加号方法,相当于该类的MetalClas的实例方法,类调用类方法,和对象调用实例方法,其实底层实现都是一样的。类也是对象。

2、SEL name

name :要添加的方法名;

添加的方法在本类里面叫的名字,但是方法的格式一定要和你需要添加的方法的格式一样,比如有无参数

传的类型 ? @selector(方法名)

3、IMP imp

实现这个方法的函数
imp:指向实现方法的指针 ??就是要添加的方法的实现部分

IMP就是Implementation的缩写,它是指向一个方法实现的指针,每一个方法都有一个对应的IMP。这里需要的是IMP,所以不能直接写方法,需要用到一个方法:class_getMethodImplementation

SEL就是一个函数的声明方法,而IMP就是这个方法的实现,也就是一个函数的指针

传的类型 ?

(1)C语言写法:(IMP)方法名? ,举例如下:

不带参数:

//C语言函数
void startEngine(id self, SEL _cmd) {
    NSLog(@"my car starts the engine");
}

这是一个 C 语言的函数,它至少包含了 self 和 _cmd 两个参数(self 代表着函数本身,而 _cmd 则是一个 SEL 数据体,包含了具体的方法地址)。如果要在这个方法中新增参数如下

带参数:

//C语言函数
void startEngine(id self, SEL _cmd, NSString *brand) {
    NSLog(@"my %@ car starts the engine", brand);
}

@implementation Car (myCar)

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if (sel == @selector(drive)) {
        class_addMethod([self class], sel, (IMP)startEngine, "v@:@");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

@end

只要在那两个必须的参数之后添加所需要的参数和类型就可以了,返回值同理,只要把方法名之前的 void 修改成我们想要的返回类型即可
(2)OC的写法:class_getMethodImplementation(self,@selector(方法名:)){ };如下:

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

这个方法也是runtime的方法,就是获得对应的方法的指针,也就是IMP。

OC写法举例如下:

@implementation Car (myCar)

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if (sel == @selector(drive)) {
        class_addMethod([self class], sel, class_getMethodImplementation(self, @selector(startEngine:)), "s@:@");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

- (void)startEngine:(NSString *)brand {
    NSLog(@"my %@ car starts the engine", brand);
}

@end

4、const char *types
要添加的方法的返回值和参数 ??叫 type encodings ;这里可以参考苹果官方文档Type Encodings

"v@:@":v:是添加方法无返回值     @表示是id(也就是要添加的类) :表示添加的方法类型   @表示:参数类型

比如:”v@:”意思就是这已是一个void类型的方法,没有参数传入。
再比如 “i@:”就是说这是一个int类型的方法,没有参数传入。
再再比如”i@:@”就是说这是一个int类型的方法,有一个参数传入。

const char *types含义表如下:

注意点:

用这个方法添加的方法是无法直接调用的,必须用performSelector:调用。

因为performSelector是运行时系统负责去找方法的,在编译时候不做任何校验;如果直接调用编译是会自动校验。

参考文章:

如何实现类方法“ + (BOOL)resolveClassMethod:(SEL) sel”

iOS Runntime 动态添加类方法并调用-class_addMethod

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-07 13:57:32  更:2021-10-07 13:59:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:44:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码