iOS_收藏程序员成长iOS_Dev

ios开发 -- runtime动态创建类、添加方法、添加实例变

2016-12-29  本文已影响3642人  LimMem

一、前言

本文主要记录如何用runtime 动态添加类 添加实例变量 添加方法等。项目中虽然很少用到,但是本着学习的态度,记录下来以便学习。
顺便给自己灌碗鸡汤:搞 iOS 学算法有意义吗?-唐巧
本文Demo 地址:demo

二、切入正题

代码走一遍

1、 添加一个集成NSObject的类 类名是MyClass

注意:调用的c语言的方法 所以不要使用@""表示字符串 应该使用""
Class MyClass = objc_allocateClassPair([NSObject class], "MyClass", 0);

2、增加实例变量

参数一、类名
参数二、属性名称
参数三、开辟字节长度
参数四、对其方式
参数五、参数类型 “@” 官方解释 An object (whether statically typed or typed id) (对象 静态类型或者id类型) 具体类型可参照官方文档
return: BOOL 是否添加成功

BOOL isSuccess = class_addIvar(MyClass, "test", sizeof(NSString *), 0, "@");

// 三目运算符
isSuccess?NSLog(@"添加变量成功"):NSLog(@"添加变量失败");

3、增加方法

给MyClass这个类添加方法;
参数一、类名
参数二、SEL 添加的方法名字
参数三、IMP指针 (IMP就是Implementation的缩写,它是指向一个方法实现的指针,每一个方法都有一个对应的IMP)
参数四、其中types参数为"i@:@“,按顺序分别表示:具体类型可参照官方文档
i 返回值类型int,若是v则表示void
@ 参数id(self)
: SEL(_cmd)
@ id(str)
V@:表示返回值是void 带有SEL参数 (An object (whether statically typed or typed id))

class_addMethod(MyClass, @selector(addMethodForMyClass:), (IMP)addMethodForMyClass, "V@:");

4、这里我们需要实现一个函数和一个方法

函数 //self和_cmd是必须的,在之后可以随意添加其他参数

static void addMethodForMyClass(id self, SEL _cmd, NSString *test) {
    // 获取类中指定名称实例成员变量的信息
    Ivar ivar = class_getInstanceVariable([self class], "test");
// 获取整个成员变量列表
//   Ivar * class_copyIvarList ( Class cls, unsigned intint * outCount );
// 获取类中指定名称实例成员变量的信息
//   Ivar class_getInstanceVariable ( Class cls, const charchar *name );
// 获取类成员变量的信息
//   Ivar class_getClassVariable ( Class cls, const charchar *name );

    // 返回名为test的ivar变量的值
    id obj = object_getIvar(self, ivar);
    NSLog(@"%@",obj);
    NSLog(@"addMethodForMyClass:参数:%@",test);
    NSLog(@"ClassName:%@",NSStringFromClass([self class]));
}

5、我们要实现这个方法

//这个方法实际上没有被调用,但是必须实现否则不会调用addMethodForMyClass()方法

- (void)addMethodForMyClass:(NSString *)string {
}

6、接着第三步 开始创建MyClass对

   id myObjc = [[MyClass alloc] init];
    NSLog(@"%@",myObjc);

这个我们也可以通过发送消息创建对象
在OC中,我们对方法的调用都会被转换成内部的消息发送执行对objc_msgSend方法的调用,掌握好消息发送,可以让我们在编程中更方便灵活。
上面的id myObjc = [[MyClass alloc] init]; 我们可以通过runtime 消息发送objc_msgSend去实现
实现[MyClass alloc] 去开辟空间 并初始化

    id myobjc = objc_msgSend(MyClass, @selector(alloc));
    myobjc = objc_msgSend(myobjc, @selector(init));

下面我给属性test赋值

NSString *str = @"我是test";
// 通过KVC的方式给myObj对象的test属性赋值
[myobjc setValue:str forKey:@"test"];

// 如果不调用- (void)addMethodForMyClass:(NSString *)string 这个方法,就不会调用static void addMethodForMyClass(id self, SEL _cmd, NSString *test) 函数

[myobjc addMethodForMyClass:@"参数"];

通过上面的所有步骤 可以运行并且在函数addMethodForMyClass()打印确定这个类是不是创建成功
好了,今天就到这结束了,如果那里有错误,欢迎大家纠正!

上一篇下一篇

猜你喜欢

热点阅读