当前位置: 首页>编程语言>正文

底层数据结构-runtime学习二

runtime中数据的结构

高级语言所编写的代码若想被机器识别,首先得翻译成汇编语言,然后再由汇编语言翻译成计算机所能识别的机器语言。高级语言有很多如:java、c++、python及Objective-C等语言,高级语言语法差别很大,但是越往底层翻译越趋向统一。

Objective-C语言是C语言的拓展,使C语言能够面向对象开发。Objective-C语言在编译时不能直接翻译成汇编语言,而是先要翻译成C语言,然后再由C语言进行汇编工作。当Objective-c代码在编译的时候,runtime系统将Objective-c代码翻译成C代码。

下面开始研究当Objective-C到C时,Objective-C中我们经常使用的实例对象、类对象、元类对象、属性及方法等它们的数据结构是怎样的以便我们能深入的了解底层都干了什么。了解底层数据结构,我们能够更好的使用runtimeAPI带来便利及启发我们在开发时的一些思想。

为了学习runtime底层,我们需要下载苹果源码objc4-750,本文围绕苹果objc4-750源码展开。源码获取方式:1.苹果开源源码 2.githup搜索

实例对象

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

Objectivie-C实例对象大多都是继承于NSObject类的子类对象,从以上源码中可以看到有一个isa指针它的类型是Classisa指针指向这个实例对象的类对象,Class类型的数据结构是typedef struct objc_class *Class;,所以类的数据结构objc_class.

类对象

struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags

    class_rw_t *data() { 
        return bits.data();
    }
    void setData(class_rw_t *newData) {
        bits.setData(newData);
    }

    void setInfo(uint32_t set) {
        assert(isFuture()  ||  isRealized());
        data()->setFlags(set);
    }

从上边源码可以看到类对象源码的大致信息。

  • isa指针为隐藏指针,指向的是该类的元类对象。
  • superclass指向的也是一个Class类型,指向的是该类的父类。
  • cache是类对象的方法缓存列表,缓存类的实例方法。
  • bits存储类里边的很多数据。如bits里的datade数据类型class_rw_t
  • data存储的数据类型class_rw_t
struct class_rw_t {
    // Be warned that Symbolication knows the layout of this structure.
    uint32_t flags;
    uint32_t version;

    const class_ro_t *ro;

    method_array_t methods;
    property_array_t properties;
    protocol_array_t protocols;
struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;
#ifdef __LP64__
    uint32_t reserved;
#endif

    const uint8_t * ivarLayout;
    
    const char * name;
    method_list_t * baseMethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars;

    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;

    method_list_t *baseMethods() const {
        return baseMethodList;
    }
};

class_ro_tclass_rw_t的比较:

  • 从字面来看class_ro_t中ro是readnoly的意思,只能读取不能修改。class_rw_t中rw是readwirte的意思,可以读写操作。
  • class_ro_t结构体存储了类在编译期间确定的属性、方法、协议以及变量。编译期完成之后,将属性,方法及协议存储在ro里边。
  • 可以往类结构中增加一些额外的方法、协议,比如在Category中写的方法,Category中的方法就是在运行时加入到类结构中的。运行时生成的类的方法、属性、协议保存在class_rw_t结构体中。
  • const ivar_list_t * ivars从这里我们可以看到ivars是一个const修饰的,所以在运行时不能给类动态的添加实例变量的。

方法

struct method_t {
    SEL name;
    const char *types;
    IMP imp;

    struct SortBySELAddress :
        public std::binary_function<const method_t&,
                                    const method_t&, bool>
    {
        bool operator() (const method_t& lhs,
                         const method_t& rhs)
        { return lhs.name < rhs.name; }
    };
};
  • SEL name方法编号,与imp函数指针一一对应。
  • types方法签名,每个方法都需要方法签名。
  • imp函数具体实现的指针。

属性

struct property_t {
    const char *name;
    const char *attributes;
};
  • name指的是属性的名称
  • attributes为属性的信息,比如类型和修饰信息。

协议

struct protocol_t : objc_object {
    const char *mangledName;
    struct protocol_list_t *protocols;
    method_list_t *instanceMethods;
    method_list_t *classMethods;
    method_list_t *optionalInstanceMethods;
    method_list_t *optionalClassMethods;
    property_list_t *instanceProperties;
    uint32_t size;   // sizeof(protocol_t)
    uint32_t flags;
    // Fields below this point are not always present on disk.
    const char **_extendedMethodTypes;
    const char *_demangledName;
    property_list_t *_classProperties;

    const char *demangledName();

    const char *nameForLogging() {
        return demangledName();
    }

    bool isFixedUp() const;
    void setFixedUp();

#   define HAS_FIELD(f) (size >= offsetof(protocol_t, f) + sizeof(f))

    bool hasExtendedMethodTypesField() const {
        return HAS_FIELD(_extendedMethodTypes);
    }
    bool hasDemangledNameField() const {
        return HAS_FIELD(_demangledName);
    }
    bool hasClassPropertiesField() const {
        return HAS_FIELD(_classProperties);
    }

#   undef HAS_FIELD

    const char **extendedMethodTypes() const {
        return hasExtendedMethodTypesField() _extendedMethodTypes : nil;
    }

    property_list_t *classProperties() const {
        return hasClassPropertiesField() _classProperties : nil;
    }
};
  • instanceMethods 必须实现的实例方法
  • classMethods 必须实现的类方法
  • optionalInstanceMethods 可选的实例方法
  • optionalClassMethods 可选的类方法

https://www.xamrdz.com/lan/5at2016583.html

相关文章: