现在我们来学习如何使用运行时动态的创建类,对象,属性,方法。
动态的创建一个类:
Class People = objc_allocateClassPair([NSObject class], "Person", 0);
- 第一个参数为你所要创建的类的超类
- 第二个参数为类名
- 第三个参数,我也不知道是什么。按照名字跟类别我觉得应该是临时的大小。
动态的为类添加成员变量:
class_addIvar(People, "_name", sizeof(NSString *), log2(sizeof(NSString *)), @encode(NSString *));
- 第一个参数为需要添加的类
- 第二个参数为增加成员变量的名字。
- 第三个参数是为成员变量申请的内存大小。
- 第四个参数不是很明白。不过我在头文件中找到了这样一句描述他的话。英语太渣翻译不出来(在网上搜索了一下,发现大概的解释是用于计算属性在内存中最佳对齐的方式,所以直接按官方给出的方法写出来就好了)
The instance variable's minimum alignment in bytes is 1<<align. The minimum alignment of an instance variable depends on the ivar's type and the machine architecture. For variables of any pointer type, pass log2(sizeof(pointer_type)).
- 第四个参数是该成员变量的类型。
动态添加方法:
void sayFunction(id self,SEL _cmd,id some)//实现sayFunction方法
{
NSLog(@"%@运行了say方法:%@",object_getIvar(self, class_getInstanceVariable([self class],"_name")),some);
}
SEL s = sel_registerName("say:");//注册方法名为say的实例方法
class_addMethod(People, s, (IMP)sayFunction, "v@:@");//为sayfunction绑定方法名say:
注册该类:
objc_registerClassPair(People);
这样我们就创建好了一个 People 类,里面含有一个 _name 成员变量,以及一个实例方法 say:
接下来我们为他添加对象,并为他的成员变量赋值:
id people = [[People alloc] init];
[people setValue:@"liu" forKey:@"_name"];
也可以使用下面的方法改变他的值
Ivar nameIvar = class_getInstanceVariable(People, "_name");
object_setIvar(people, nameIvar, @"lala");
接下来动态的运行方法,使用objc_msgSend()方法。注意,这里要讲该方法强制转换为多参数。不然会报错:
((void(*)(id, SEL,id))objc_msgSend)(people,s,@"大家好");
运行一下:
![](https://img.haomeiwen.com/i1863852/cf48636f632f7baa.png)
网友评论