最近闲来无事,打算对objc/runtime
进行一番研究,今晚把API翻了一遍,拿出了如下的一些有趣代码,本代码需事先导入部分objc/runtime
中的头文件,如下所示
1
2
| #import <objc/runtime.h>
#import <objc/message.h>
|
动态创建类#
类的创建分为两步,添加成员变量
需要在这两步操作之间,添加成员方法
则无此要求
- Class
objc_allocateClassPair
(Class superClass,const char* className,size_t extraBytes); - void objc_registerClassPair(Class cls);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| //开始类的定义
Class Test= objc_allocateClassPair([NSObject class], "Test", 0);
//为类添加变量
class_addIvar(Test, "_name", sizeof(NSString*), log2(sizeof(NSString*)), @encode(NSString*));
//为类添加方法
//1.注册名为 test: 的方法
SEL s = sel_registerName("test:");
//2.定义函数实现,此处的IMP是函数指针,原型为 typedef id (*IMP)(id, SEL, ...);
IMP i = imp_implementationWithBlock(^(id this,id some){
NSLog(@"%@",some);
return @111;
});
//关联Test,s,i,并确认函数签名
class_addMethod(Test, s, i, "i@:");
//结束类的定义
objc_registerClassPair(Test);
|
动态创建对象#
采用上边代码创建的Test
类创建对象,并通过该对象操作成员方法和成员变量
1
2
3
4
5
6
7
8
| //创建对象
id t = [[Test alloc]init];
//KVC 动态改变 对象t 中的实例变量
[t setValue:@"张三" forKey:@"name"];
NSLog(@"%@",[t valueForKey:@"name"]);
//调用 t 对象中的 s 方法选择器对于的方法
id result = objc_msgSend(t, s,@"传送内容");
NSLog(@"%@",result);
|
运行结果#
1
2
3
| 2014-08-15 00:11:00.239 Test[44644:303] 张三
2014-08-15 00:11:00.240 Test[44644:303] 传送内容
2014-08-15 00:11:00.241 Test[44644:303] 111
|