美文网首页
RunTime的一些知识点之对象二

RunTime的一些知识点之对象二

作者: bonoCat | 来源:发表于2017-05-18 17:30 被阅读55次

    RunTime的一些知识点之对象二

    主要是对文档的翻译,希望能有一个比较全面的理解

    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;
    /* Use `Class` instead of `struct objc_class *` */
    

    class 是一个结构体,包含super_class、name、version、info、instance_size、ivars、methodLists、cache、protocols

    能做些什么?

    对象copy

    OBJC_EXPORT id object_copy(id obj, size_t size)
        OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0)
        OBJC_ARC_UNAVAILABLE;
    

    对象销毁(ARC中不能使用)

    OBJC_EXPORT id object_dispose(id obj)
        OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0)
        OBJC_ARC_UNAVAILABLE;
    

    获取指定对象的class

    OBJC_EXPORT Class object_getClass(id obj) 
        OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
    

    设置指定对象的类

    OBJC_EXPORT Class object_setClass(id obj, Class cls) 
        OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
    

    判断是否为class对象

    OBJC_EXPORT BOOL object_isClass(id obj)
        OBJC_AVAILABLE(10.10, 8.0, 9.0, 1.0);
        
    

    实例说明

        Engineer *person = [[Engineer alloc] init];
        NSLog(@"%@", object_isClass([Engineer class]) ? @"1" : @"0"); // 0
        NSLog(@"%@", object_isClass(person) ? @"1" : @"0");           // 1
    

    获取实例变量值

    /*
    * @note \c object_getIvar is faster than \c object_getInstanceVariable if the Ivar
     *  for the instance variable is already known.
    */
    OBJC_EXPORT id object_getIvar(id obj, Ivar ivar) 
        OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
    
        /// 获取实例变量
        Ivar ivar = class_getInstanceVariable([self class], "_name");
       object_getIvar(self, ivar);
    

    设置实例变量的值

    /*
      * @note Instance variables with known memory management (such as ARC strong and weak)
     *  use that memory management. Instance variables with unknown memory management 
     *  are assigned as if they were unsafe_unretained.
     *  unsafe_unretained 会造成未知的内存管理问题
     * @note \c object_setIvar is faster than \c object_setInstanceVariable if the Ivar
     *  for the instance variable is already known.
     */
    OBJC_EXPORT void object_setIvar(id obj, Ivar ivar, id value) 
        OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
        
    OBJC_EXPORT void object_setIvarWithStrongDefault(id obj, Ivar ivar, id value) 
        OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0);
     /// 速度慢  
     OBJC_EXPORT Ivar object_setInstanceVariable(id obj, const char *name, void *value)
        OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0)
        OBJC_ARC_UNAVAILABLE;
        
     OBJC_EXPORT Ivar object_setInstanceVariableWithStrongDefault(id obj, const char *name, void *value)
        OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0)
        OBJC_ARC_UNAVAILABLE;
        
     OBJC_EXPORT Ivar object_getInstanceVariable(id obj, const char *name, void **outValue)
        OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0)
        OBJC_ARC_UNAVAILABLE;
    

    获取 class MetaClass

    // Returns the class of an object.
    OBJC_EXPORT Class object_getClass(id obj) 
        OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
        
    // Returns the class definition of a specified class.
    OBJC_EXPORT Class objc_getClass(const char *name)
        OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
        
    /// 获取元类 
    OBJC_EXPORT Class objc_getMetaClass(const char *name)
        OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
     
    

    实例说明

      /// 定义一个Engineer的class
        Class className = objc_getClass("Engineer");
        
        /// 是否为class
        if (object_isClass(className)) {
            
            /// 获取 class 的名称
            const char *name_ = object_getClassName([[className alloc] init]);
            
            /// 得到 Engineer
            NSLog(@"%s", name_);
            
        }
    

    元类理解

        /* metaClass 是类的类
         
         当你向一个对象发送消息时,runtime会在这个对象所属的那个类的方法列表中查找。
         
         当你向一个类发送消息时,runtime会在这个类的meta-class的方法列表中查找。
         meta-class之所以重要,是因为它存储着一个类的所有类方法。每个类都会有一个单独的meta-class,因为每个类的类方法基本不可能完全相同。
         保证设计的完整性, metaclass 也是对象 也就有 isa 
         
         */
    
        NSLog(@"元类 %p", objc_getMetaClass("Engineer"));
        NSLog(@"元类 %p", object_getClass([[Engineer class] class]));
        
    //    2017-05-18 16:36:06.259 RunTime[19555:203675] 元类 0x108d5a188
    //    2017-05-18 16:36:07.474 RunTime[19555:203675] 元类 0x108d5a188
    
    /*
    * objc_getClass 不但执行这个方法,还会判断是否注册
    * objc_lookUpClass 直接执行
    */
    OBJC_EXPORT Class objc_lookUpClass(const char *name)
        OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
    
    /*
     * @note This function is the same as \c objc_getClass, but kills the process if the class is not found.
     * @note This function is used by ZeroLink, where failing to find a class would be a compile-time link error without ZeroLink.
    */
    OBJC_EXPORT Class objc_getRequiredClass(const char *name)
        OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0);
    

    相关文章

      网友评论

          本文标题:RunTime的一些知识点之对象二

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