Objective-C 对象实际上是一个C里面的结构体指针,这个我们可以通过id类型理解,大家都知道id可以指向任意对象,id本身是一个对象,然后是个指针,所以它指向对象时,不要加“ * ”。
下面是id类型的定义:
/// id 是一个指向 objc_object 结构体的指针.
typedef struct objc_object *id;
Objective-C 类实际上也是一个C里面的结构体指针,这个我们通过Class类型理解。
/// 一个不透明的类型代表一个Objective-C类.
typedef struct objc_class *Class;
那么 objc_object 和 objc_class 这两个结构体又表示了些什么东西?
objc_object 结构体的定义:
/// Represents an instance of a class.
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
objc_class 结构体的定义:
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
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 // 协议链表
} OBJC2_UNAVAILABLE;
现在我们列出来了两个结构体的定义,发现了一个大问题,它们里面都有一个叫 isa 的变量。
这个 isa 是干什么的呢?看下图:
当对象初始化时,会分配内存,并初始化其成员变量,也就是为对象的结构体 objc_class 分配内存,让其中的 isa 指针可以访问类以及其继承体系。
也就是说当我们的对象是一个实例的时候,isa指向实例所属的类;当对象为类的时候,isa指向meta-class(元类)。
其它相关结构体中的参数,在消息机制中才会解释。元类这个我不作解释了。
总结:
1、Objective-C 的实例和类都是一个对象;
2、Objective-C 的对象实际上就是一个结构体;
3、Objective-C 的对象是通过 isa 指针获取类的信息。