RunTime的一些知识点之对象二

2017-05-18  本文已影响55人  bonoCat

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);
上一篇下一篇

猜你喜欢

热点阅读