星空网 > 软件开发 > 操作系统

runtime 方法替换 和 动态添加类方法 结合使用

原文地址:runtime 方法替换 和 动态添加类方法 结合使用 这个也是我自己写的哦,实现了我自己的想法

前言:方法替换,可以替换任意外部类的方法,而动态添加方法只能实现在被添加类创建的对象里,但是将方法替换和动态添加方法结合使用,可以实现,对任意外部类动态添加需要的方法,这个方法可以是类方法也可以是实例方法。

缺陷:1、含参数的方法难以处理,参数值需要根据实际业务逻辑而定。

Create Person.h and Person.m

Person.h:

1
2
3
4
5
#import <Foundation/Foundation.h>

@interface Person : NSObject

@end

Person.m:

1
2
3
4
5
#import "Person.h"

@implementation Person

@end

Create OtherPerson.h and OtherPerson.m

OtherPerson.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//
// Created by HEYANG on 16/1/11.
// Copyright © 2016年 HEYANG. All rights reserved.
//

#import "OtherPerson.h"
#import <objc/message.h>

@implementation OtherPerson


+(void)load{
Class clazz = NSClassFromString(@"Person");

//获取替换前的类方法
Method instance_eat =
class_getClassMethod(clazz, @selector(resolveInstanceMethod:));
//获取替换后的类方法
Method instance_notEat =
class_getClassMethod(self, @selector(hy_resolveInstanceMethod:));

//然后交换类方法
method_exchangeImplementations(instance_eat, instance_notEat);

//获取替换前的类方法
Method class_eat =
class_getClassMethod(clazz, @selector(resolveClassMethod:));
//获取替换后的类方法
Method class_notEat =
class_getClassMethod(self, @selector(hy2_resolveClassMethod:));

//然后交换类方法
method_exchangeImplementations(class_eat, class_notEat);

}

void eat_1(id self,SEL sel)
{
NSLog(@"到底吃不吃饭了");
NSLog(@"%@ %@",self,NSStringFromSelector(sel));
}
void eat_2(id self,SEL sel, NSString* str1,NSString* str2)
{
NSLog(@"到底吃不吃饭了");
NSLog(@"%@ %@",self,NSStringFromSelector(sel));
NSLog(@"打印两个参数值:%@ and %@",str1,str2);
}


+(BOOL)hy_resolveInstanceMethod:(SEL)sel{
//当sel为实现方法中 有 eat 方法
if (sel == NSSelectorFromString(@"eat")) {
//就 动态添加eat方法

// 第一个参数:给哪个类添加方法
// 第二个参数:添加方法的方法编号
// 第三个参数:添加方法的函数实现(函数地址)
// 第四个参数:函数的类型,(返回值+参数类型) v:void @:对象->self :表示SEL->_cmd
class_addMethod(self, sel, (IMP)eat_1, "v@:");
}
return YES;
}
+(BOOL)hy2_resolveClassMethod:(SEL)sel{

if (sel == NSSelectorFromString(@"eat:with:")) {

class_addMethod(objc_getMetaClass("Person"), sel, (IMP)eat_2, "v#:@@");
}

return YES;
}

@end

last In file ‘main.m’:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
*
* Swap Method and Dynamic add Method (交换方法和动态添加方法)
*
*/

#import <Foundation/Foundation.h>

//ignore undeclared warm 忽视未声明的警告
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"

int main(int argc, const char * argv[]) {
@autoreleasepool {
//get this Person class 拿到了这个Person类
Class clazz = NSClassFromString(@"Person");
//get this Person Instance 拿到这个Person实例
id person = [[clazz alloc] init];

//send message to 'eat' method in Person Class or Person Instance
//发送消息给Person类或者Person实例的‘eat’方法 不含参数
[person performSelector:@selector(eat) withObject:nil];
//发送消息给Person类的‘eat’方法 含两个参数
[clazz performSelector:@selector(eat:with:)
withObject:@"Hello"
withObject:@"World"];
}
return 0;
}

#pragma clang diagnostic pop

the code test result

runtime 方法替换 和 动态添加类方法 结合使用images/loading.gif' data-original="http://img.hoop8.com/attachments/1601/7953664451394.png" />

download

download github code source

Note

Before use import <objc/message.h> ,need following:

runtime 方法替换 和 动态添加类方法 结合使用






原标题:runtime 方法替换 和 动态添加类方法 结合使用

关键词:

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

内幕交易:https://www.goluckyvip.com/tag/13788.html
玺堡家居:https://www.goluckyvip.com/tag/13789.html
大量套现:https://www.goluckyvip.com/tag/1379.html
美国海运:https://www.goluckyvip.com/tag/13790.html
甩柜是什么:https://www.goluckyvip.com/tag/13791.html
外贸样品:https://www.goluckyvip.com/tag/13794.html
亚马逊掀起算法革命:A9已死 COSMO当立? :https://www.kjdsnews.com/a/1836493.html
2月新茶饮开店腰斩 加盟门槛一降再降 :https://www.kjdsnews.com/a/1836494.html
相关文章
我的浏览记录
最新相关资讯
海外公司注册 | 跨境电商服务平台 | 深圳旅行社 | 东南亚物流