美文网首页
iOS Runtime

iOS Runtime

作者: cjnwan | 来源:发表于2016-01-28 11:22 被阅读82次

    id和Class

    typedef struct objc_class *Class //Class是一个指向objc_class结构体的指针
    typedef struct objc_object *id //id是一个指向objc_object结构体的指针
    
    struct objc_object { //表示一个对象
    Class isa  OBJC_ISA_AVAILABILITY; //指向该对象所属的类(存放着成员变量和动态方法)
    };
    
    struct objc_class { //表示一个类
    Class isa  OBJC_ISA_AVAILABILITY;//指向该类的元数据(static成员变量和static方法(+))
    
    #if !__OBJC2__
        Class super_class   //父类                                     
        const char *name //类名                                        
        long version  //版本                                           
        long info       //信息                                            
        long instance_size //实例变量大小                                      
        struct objc_ivar_list *ivars //变量                            
        struct objc_method_list **methodLists    //方法                
        struct objc_cache *cache    //缓存(方法)                            
        struct objc_protocol_list *protocols   //协议                  
    #endif
    
    } 
    

    SEL

    • 在OC中用selector表示,表示一个方法的选择器

        typedef struct objc_selector *SEL
        
        struct objc_selector{
            char *name; //名称
            char *type; //类型
        }
      

    IMP

    typedef id (*IMP)(id, SEL, ...); //指向函数的指针
    

    Method

    typedef struct objc_method *Method //代表着类中的某个方法的类型
    struct objc_method {
        SEL method_name  //名称                                        
        char *method_types    //类型                                   
        IMP method_imp     //实现                                      
    }                                                            
    

    IVar

    typedef struct objc_ivar *Ivar;//对象中的变量
    
    struct objc_ivar {
        char *ivar_name    //名称                                      
        char *ivar_type       //类型                                 
        int ivar_offset       //基地址偏移量                              
    #ifdef __LP64__
        int space           //占用空间                                      
    #endif
    } 
    

    Property

    typedef struct objc_property *objc_property_t;//对象声明的属性
    typedef struct {
        const char *name;           //名称
        const char *value;          //值(通常是空的)
    } objc_property_attribute_t;
    

    Cache

    typedef struct objc_cache *Cache //方法缓存表
    struct objc_cache {
        unsigned int mask /* total = mask + 1 */                 
        unsigned int occupied                                    
        Method buckets[1]                                        
    

    };

    Category

    typedef struct objc_category *Category; //一个类的扩展
    struct objc_category {
        char *category_name  //扩展名                                    
        char *class_name    //类名                                    
        struct objc_method_list *instance_methods  //实例方法列表              
        struct objc_method_list *class_methods  //类的方法列表                  
        struct objc_protocol_list *protocols // 协议列表
    } //扩展都是对方法的操作,所以不能添加属性
    
    添加属性的方法:
    objc_setAssociatedObject
    
    objc_getAssociatedObject
    
    objc_removeAssociatedObjects
    

    消息(过程)

    • 检测selector是不是要忽略

    • 检测target是不是nil对象,对nil发送的消息都会被忽略掉

    • 查找这个类的IMP,先从(isa指向的类的)Cache中查找,找到了就执行方法。(类方法会从metaclass中查找)

    • 如果找不到就去方法分发表中查找,找不到就去父类中查找,直到NSObject

    • 再找不到就去开始方法动态解析

      • resolveInstanceMethod:决定是否动态添加方法
      • forwardingTargetForSelector(重定向):指定哪个对象响应selector.指定self或者nil会进入第三步
      • methodSignatureForSelector:指定方法签名,返回nil,不处理,否则进入下一步
      • forwardInvocation(转发):修改方法,修改响应对象,不成功则进入下一步
      • doesNotRecognizeSelector:没有实现就会crash

    Method Swizzing

    • 改变内置类的方法的实现
    • Swizzling在load方法中实现
    • 使用dispatch_once保证只交换一次

    相关文章

      网友评论

          本文标题:iOS Runtime

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