Objective-c语法

Objective-C的本质

  • 平时编写的OC代码,底层实现其实都是C/C++代码
1
Objective-C -> C/C++ -> 汇编语言 -> 机器语言
  • OC的面向对象都是基于C/C++的数据结构实现的,即 结构体

NSObject的底层实现

1
2
3
4
5
6
7
8
9
@interface NSObject {
Class isa;
}
@end

底层结构体形式:
struct NSObject_IMPL {
Class isa;
}
  • 创建一个实例对象,至少需要多少内存?

    • 至少需要8个字节
      1
      2
      #import <objc/runtime.h>
      class_getInstanceSize([NSObjcet class]);
  • 创建一个实例对象,实际上分配了多少内存?

    • 实际分配了16个字节
    • 底层是Buckets size, 16, 32, 48, 64…. 都是16的位数
      1
      2
      #import <objc/runtime.h>
      malloc_size((__bridge const void *)obj)

OC对象的分类

  • instance对象(实例对象)

    • alloc出来的对象,在内存中存储的信息包括:
      1. isa指针
      2. 其他成员变量
  • class对象(类对象)

    • 每个类在内存中有且只有一个class对象
    • class对象在内存中存储的信息主要包括:
      1. isa指针
      2. superClass指针
      3. 类的属性信息(property)、类的对象方法信息(instance method)
      4. 类的协议信息(protocol)、类的成员变量信息(ivar)
      5. ……
  • meta-class对象(元类对象)

    1
    Class objectMetaClass = objc_getClass([NSObject class]);//Runtime API

    小结:

    • objectMetaClass是NSObject的meta-class对象(元类对象)
    • 每个类在内存中只有一个meta-class对象
    • meta-class对象和class对象的内存结构是一样的,但是用途不一样
      主要包括:
      1. isa指针
      2. superclass指针
      3. 类的方法信息(class method)
      4. ……
  • 查看Class是否为meta-class,方法:

    1
    Bool result = class_isMetaClass([NSObjce class]);

isa指针

image

  • instance的 isa 指向class
    • 当调用 对象方法 时,通过instance的 isa 找到class,最后找到 对象方法 的实现进行调用
  • class的 isa 指向meta-class
    • 当调用 类方法 时,通过class的 isa 找到meta-class,最后找到 类方法 的实现进行调用
      image

** note: ** 从64位开始,isa需要进行一次位运算,才能计算出真实地址

class对象的superclass指针

image

** note: ** 当student的instance对象要调用Person的对象方法时,会先通过 isa 找到Student的class,然后通过 superclass 找到Person的class,最后找到对象方法的实现进行调用

meta-class对象的superclass指针

image

** note: ** 当Student的class要调用Person的类方法时,会先通过 isa 找到Student的meta-class,然后通过 superclass 找到Person的meta-class,最后找到类方法的实现进行调用

isa、superclass总结

image

  1. instance的isa指向class
  2. class的isa指向meta-class
  3. meta-class的isa指向基类的meta-class
  4. class的superclass指向父类的class
    如果没有父类,superclass指针为nil
  5. meta-class的superclass指向父类的meta-class
    基类的meta-class的superclass指向基类的class
  6. instance调用对象方法的轨迹
    isa找到class,方法不存在,就通过superclass找父类
  7. class调用类方法的轨迹
    isa找meta-class,方法不存在,就通过superclass找父类

64位isa指针

  • 从64bit开始,isa需要进行一次位运算(isa地址 & ISA_MASK),才能计算出真实地址
    1
    2
    3
    4
    5
    # if __arm64__
    # define ISA_MASK 0x0000000ffffffff8ULL
    # elif __x86_64__
    # define ISA_MASK 0x00007ffffffffff8ULL
    # endif

struct objc_class的结构

  • class、meta-class对象的本质结构都是struct objc_class

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize; // instance对象占用的内存空间
    #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;
    };

    struct class_rw_t {
    uint32_t flags;
    uint32_t version;
    const class_ro_t *ro;
    method_list_t * methods; // 方法列表
    property_list_t *properties; // 属性列表
    const protocol_list_t * protocols; // 协议列表
    Class firstSubclass;
    Class nextSiblingClass;
    char *demangledName;
    };

    #define FAST_DATA_MASK 0x00007ffffffffff8UL
    struct class_data_bits_t {
    uintptr_t bits;
    public:
    class_rw_t* data() {
    return (class_rw_t *)(bits & FAST_DATA_MASK);
    }
    };

    /* OC对象 */
    struct hx_objc_object {
    void *isa;
    };

    /* 类对象 */
    struct hx_objc_class : hx_objc_object {
    Class superclass;
    cache_t cache;
    class_data_bits_t bits;
    public:
    class_rw_t* data() {
    return bits.data();
    }

    hx_objc_class* metaClass() {
    return (hx_objc_class *)((long long)isa & ISA_MASK);
    }
    };
  • 用如下方法进行断点查看,内部结构内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //实例对象
    hx_objc_class *studentClass = (__bridge hx_objc_class *)([Student class]);
    hx_objc_class *personClass = (__bridge hx_objc_class *)([Person class]);

    //类对象
    class_rw_t *studentClassData = studentClass->data();
    class_rw_t *personClassData = personClass->data();

    //元类对象
    class_rw_t *studentMetaClassData = studentClass->metaClass()->data();
    class_rw_t *personMetaClassData = personClass->metaClass()->data();

参考