美文网首页iOS_收藏程序员成长iOS_Dev
ios开发 -- runtime动态创建类、添加方法、添加实例变

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

作者: LimMem | 来源:发表于2016-12-29 11:20 被阅读3642次

    一、前言

    本文主要记录如何用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()打印确定这个类是不是创建成功
    好了,今天就到这结束了,如果那里有错误,欢迎大家纠正!

    相关文章

      网友评论

        本文标题:ios开发 -- runtime动态创建类、添加方法、添加实例变

        本文链接:https://www.haomeiwen.com/subject/jpguvttx.html