美文网首页iOS开发iOS学习iOS Developer
runtime运行时机制初探秘(二)

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

作者: 呜啦啦啦拉拉 | 来源:发表于2016-08-28 17:15 被阅读31次

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

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

    运行一下:


    控制台输出结果

    相关文章

      网友评论

        本文标题:runtime运行时机制初探秘(二)

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