iOS isa解析

2020-01-09  本文已影响0人  楼上那只猫

在创建一个对象的时候,我们有时会用id来表示,系统会在运行时找到对象实际所属的类,这是怎么实现的呢?id又是什么?

/// A pointer to an instance of a class.
typedef struct objc_object *id;

/// Represents an instance of a class.
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

可以看到,id实际是一个结构体指针,这个结构体中包含一个isa成员,类型为Class

每个对象都最终都继承于NSObject,通过点击NSObject,可以发现如下:

@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
    Class isa  OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}

有一个isa成员变量,其类型是Class类型。
创建一个对象,就是对一个类进行实例化,因此需要知道类的模板,根据这个模板来创建实例对象,因此这个Class实际上就是表示类的模板,点击可以查看到实际是一个结构体。

/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;
struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

注意,这个结构体中也有一个是isa指针,因此可以判断Class其实也是一个对象,叫做类对象,也就是说,在创建类的实例对象的时候,实例对象的isa会指向对象所属类的类对象,这个类对象中包含创建实例所需的基本信息,包含方法列表,属性列表,协议列表等。
那么,类对象中的isa指向的是哪里?
可以看到,类对象中包含的是创建该类的实例对象所需的基本信息,并没包含创建类对象所需的信息,因此,类对象中的isa实际指向的是描述这个类对象的类,称为元类
元类中包含这个类对象的基本信息,类方法列表等信息。
元类中也有isa指针,元类中的isa指针指向根类。

上一篇 下一篇

猜你喜欢

热点阅读