runtime运行时机制初探秘(二)

现在我们来学习如何使用运行时动态的创建类,对象,属性,方法。
动态的创建一个类:

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<

  • 第四个参数是该成员变量的类型。

动态添加方法:

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,@"大家好");

运行一下:


控制台输出结果

你可能感兴趣的:(runtime运行时机制初探秘(二))