Objective-C是一门动态语言,它的很多东西都是运行的时候才决定的,比如调用的方法等等。利用这个特性可以做很多事情,可以动态的创建类、添加方法、属性,今天就来通过一个例子练习一下。

        要使用runtime首先我们要引入头文件#import <objc/runtime.h>然后在- (void)viewDidLoad中动态创建类:

1
2
3
4
5
6
7
8
9
10
11
//动态创建类
Class person = objc_allocateClassPair([NSObject class], "Person", 0);
//添加变量
class_addIvar(person, "name", sizeof(NSString *), 0, "@");
//添加函数 sayHi
class_addMethod(person, @selector(sayHi:), (IMP)sayHi, "v@:");
objc_registerClassPair(person);
//初始化一个person对象
id Tom = [[person alloc] init];
[Tom setValue:@"Tom" forKey:@"name"];
[Tom sayHi:@"Jeck"];

        上述代码,我们通过objc_allocateClassPair()创建了一个继承NSObjectperson的子类,然后通过objc_registerClassPair()这个函数注册了person类,下面我们就可以使用这个类了,使用之前我们在给person类中添加一个name属性和sayHi:方法,分别通过class_addIvar()class_addMethod()来添加,接下来我们要实现我们添加的sayHi:方法,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
//这个函数必须写,要不然xcode会报错,实际运行的时候,这个函数是不会调用的
-(void)sayHi:(NSString *)name
{

}

//运行的时候,会调用这个方法
static void sayHi(id self, SEL _cmd, NSString *name)
{
Ivar n = class_getInstanceVariable([self class], "name");
id a = object_getIvar(self, n);
NSLog(@"hello %@,my name is %@",name,a);
}

        static void sayHi(id self, SEL _cmd, NSString *name)这个就是我们运行时候调用的方法,其中self使我们使用person创建的对象Tom,_cmd是调用的方法名,name就是传过来的参数,如果有多个参数,可以写成static void sayHi(id self, SEL _cmd, NSString *name,...)省略号可以填写你愿意添加的参数。

        这样我们就利用runtime动态的创建了一个person类,包括了name属性和sayHi:方法,运行如结果如下图: