runtime基础教程(1)-OC元素认知

Objective-C的元素认知

id和Class

  • 打开objc/objc.h>文件可以看到如下定义:
#if !OBJC_TYPES_DEFINED
// Class是一个指向objc_class结构体的指针. Class就是我们所说的类
typedef struct objc_class *Class;

// isa是一个指向objc_class结构体的指针
struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};

// id是一个指向objc_object结构体的指针, id就是我们所说的对象
typedef struct objc_object *id;
#endif
  • 打开objc/runtime.h>文件, objc_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;

由以上代码可见,类与对象的区别就是类比对象多了很多特征成员,类也可以当做一个objc_object来对待,也就是说类和对象都是对象,分别称作类对象(class object)和实例对象(instance object),这样我们就可以区别对象和类了。

  • isa:objc_object(实例对象)中isa指针指向的类结构称为class(也就是该对象所属的类)其中存放着普通成员变量与动态方法(“-”开头的方法);类中的isa指针指向的类结构称为metaclass,其中存放着static类型的成员变量与static类型的方法(“+”开头的方法)。

  • super_class: 指向该类的父类的指针,如果该类是根类(如NSObject或NSProxy),那么super_class就为nil。

  • 类与对象的继承层次网上有一个经典的图

    • 所有的metaclass中isa指针都是指向根metaclass,而根metaclass则指向自身。根metaclass是通过继承根类产生的,与根class结构体成员一致,不同的是根metaclass的isa指针指向自身。

SEL

  • SEL是selector在Objective-C中的表示类型。selector可以理解为区别方法的ID。
typedef struct objc_selector *SEL;
// objc_selector的定义如下:
struct objc_selector {
    char *name;                  OBJC2_UNAVAILABLE;// 名称
    char *types;                 OBJC2_UNAVAILABLE;// 类型
};

IMP

  • 它在objc.h中得定义如下:
typedef id (*IMP)(id, SEL, ...);

IMP是“implementation”的缩写,它是由编译器生成的一个函数指针。当你发起一个消息后(下文介绍),这个函数指针决定了最终执行哪段代码。

Method

  • Method代表类中的某个方法的类型
typedef struct objc_method *Method;
// objc_method的定义如下:
struct objc_method {
    SEL method_name              OBJC2_UNAVAILABLE; // 方法名
    char *method_types           OBJC2_UNAVAILABLE; // 方法类型
    IMP method_imp               OBJC2_UNAVAILABLE; // 方法实现
}

方法名method_name类型为SEL,上文提到过。
方法类型method_types是一个char指针,存储着方法的参数类型和返回值类型。
方法实现method_imp的类型为IMP,上文提到过

Ivar

  • Ivar代表类中实例变量的类型
typedef struct objc_ivar *Ivar;
// objc_ivar的定义如下:
struct objc_ivar {
    char *ivar_name      OBJC2_UNAVAILABLE; // 变量名
    char *ivar_type      OBJC2_UNAVAILABLE; // 变量类型
    int ivar_offset      OBJC2_UNAVAILABLE; // 基地址偏移字节
#ifdef __LP64__
    int space            OBJC2_UNAVAILABLE; // 占用空间
#endif
}

objc_property_t

// objc_property_t是属性,它的定义如下:
typedef struct objc_property *objc_property_t;

objc_property是内置的类型,与之关联的还有一个objc_property_attribute_t,它是属性的attribute,也就是其实是对属性的详细描述,包括属性名称、属性编码类型、原子类型/非原子类型等。它的定义如下:

typedef struct {
    const char *name; // 名称
    const char *value;  // 值(通常是空的)
} objc_property_attribute_t;

Cache

// Catch的定义如下:
typedef struct objc_cache *Cache
// objc_cache的定义如下:
struct objc_cache {
    unsigned int mask                   OBJC2_UNAVAILABLE;
    unsigned int occupied               OBJC2_UNAVAILABLE;
    Method buckets[1]                   OBJC2_UNAVAILABLE;
};

mask: 指定分配cache buckets的总数。在方法查找中,Runtime使用这个字段确定数组的索引位置。
occupied: 实际占用cache buckets的总数。
buckets: 指定Method数据结构指针的数组。这个数组可能包含不超过mask+1个元素。需要注意的是,指针可能是NULL,表示这个缓存bucket没有被占用,另外被占用的bucket可能是不连续的。这个数组可能会随着时间而增长。
objc_msgSend(下文讲解)每调用一次方法后,就会把该方法缓存到cache列表中,下次的时候,就直接优先从cache列表中寻找,如果cache没有,才从methodLists中查找方法。

Category

// 它可以动态的为已存在的类添加新的方法
typedef struct objc_category *Category;
// objc_category的定义如下:
struct objc_category {
    char *category_name                           OBJC2_UNAVAILABLE; // 类别名称
    char *class_name                              OBJC2_UNAVAILABLE; // 类名
    struct objc_method_list *instance_methods     OBJC2_UNAVAILABLE; // 实例方法列表
    struct objc_method_list *class_methods        OBJC2_UNAVAILABLE; // 类方法列表
    struct objc_protocol_list *protocols          OBJC2_UNAVAILABLE; // 协议列表
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值