美文网首页
runtime(一)--runtime

runtime(一)--runtime

作者: 小歪子go | 来源:发表于2017-12-07 14:50 被阅读0次

    iOS Runtime原理

    runtime的原理

    ios的sdk中 usr/include/objc文件夹下面有这样几个文件


    都是和运行时相关的头文件,其中主要使用的函数定义在message.h和runtime.h这两个文件中。 在message.h中主要包含了一些向对象发送消息的函数,这是OC对象方法调用的底层实现。

    使用时,需要导入文件,导入如:

    #import <objc/message.h>
    #import <objc/runtime.h>
    

    操作对象的类型的定义
    /// An opaque type that represents a method in a class definition. 一个类型,代表着类定义中的一个方法
    typedef struct objc_method *Method;

    /// An opaque type that represents an instance variable.代表实例(对象)的变量
    typedef struct objc_ivar *Ivar;

    /// An opaque type that represents a category.代表一个分类
    typedef struct objc_category *Category;

    /// An opaque type that represents an Objective-C declared property.代表OC声明的属性
    typedef struct objc_property *objc_property_t;

    // Class代表一个类,它在objc.h中这样定义的 typedef struct objc_class *Class;

    struct objc_class {
        Class isa  OBJC_ISA_AVAILABILITY;
    
    #if !__OBJC2__
        Class super_class                                        OBJC2_UNAVAILABLE;
        const char *name                                         OBJC2_UNAVAILABLE;
        long version                                             OBJC2_UNAVAILABLE;
        long info                                                OBJC2_UNAVAILABLE;
        long instance_size                                       OBJC2_UNAVAILABLE;
        struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
        struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
        struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
        struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
    #endif
    
    } OBJC2_UNAVAILABLE;
    

    这些类型的定义,对一个类进行了完全的分解,将类定义或者对象的每一个部分都抽象为一个类型type,对操作一个类属性和方法非常方便。OBJC2_UNAVAILABLE标记的属性是Ojective-C 2.0不支持的,但实际上可以用响应的函数获取这些属性,例如:如果想要获取Class的name属性,可以按如下方法获取:

    Class classPerson = Person.class;
    // printf("%s\n", classPerson->name); //用这种方法已经不能获取name了 因为OBJC2_UNAVAILABLE
    const char *cname  = class_getName(classPerson);
    printf("%s", cname); // 输出:Person
    

    函数的定义
    对对象进行操作的方法一般以object_开头
    对类进行操作的方法一般以class_开头
    对类或对象的方法进行操作的方法一般以method_开头
    对成员变量进行操作的方法一般以ivar_开头
    对属性进行操作的方法一般以property_开头开头
    对协议进行操作的方法一般以protocol_开头
    根据以上的函数的前缀 可以大致了解到层级关系。

    对于以objc_开头的方法,则是runtime最终的管家,可以获取内存中类的加载信息,类的列表,关联对象和关联属性等操作。

    例如:使用runtime对当前的应用中加载的类进行打印

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        unsigned int count = 0;
        Class *classes = objc_copyClassList(&count);
        for (int i = 0; i < count; i++) {
            const char *cname = class_getName(classes[i]);
            printf("%s\n", cname);
        }
    }
    

    相关文章

      网友评论

          本文标题:runtime(一)--runtime

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