iOS 面试汇总 - OC语法

Objective-C的本质

  • OC代码底层都是C\C++代码
  • OC的面向对象都是基于C\C++的数据结构实现的
  • OC是结构体

Objective-C对象的内存分配

1.NSObject对象:

  • NSObject本质是一个只含有isa指针的结构体,一个isa指针所占内存大小为8个字节,但严格意义上来讲系统会分配16个字节,实际只使用了8个字节,所以也可以说NSObject的占用内存大小就是其isa指针所占内存大小。
  • NSObject对象的地址也就是结构体的地址,也就是isa指针的地址

《iOS 面试汇总 - OC语法》 NSObject转成结构体的形式

2.子类对象:

  • Student转成结构体如下图:在64位编译器下,一个isa指针为8个字节,由于内存对齐,系统会再分配8个字节,但int类型实际只占用4个字节,所以Student对象占用内存大小为16个字节。
  • Student对象的地址也是结构体的地址,即首地址,isa指针的地址。

《iOS 面试汇总 - OC语法》

《iOS 面试汇总 - OC语法》 Student转成结构体的形式

3.验证方法:

  • 通过Runtime运行时函数class_getInstanceSize([NSObject class])获取成员变量占用内存的大小。
  • 通过导入<malloc/malloc.h>头文件,调用malloc_size((__bridge void *)object)函数获取实际分配内存大小。
  • 通过Runtime源码去查看allocWithZone的底层实现,会发现系统会分配不小于16个字节的内存。
  • 通过Debug -> Debug Workflow -> View Memory 来查看类的内存地址分配情况。

《iOS 面试汇总 - OC语法》 allocWithZone的底层实现
《iOS 面试汇总 - OC语法》 Debug调试查看内存分配情况

Objective-C对象的分类

1.Objective-C对象,简称OC对象,主要分为三种:

  • instance 对象(实例对象)
  • class 对象(类对象)
  • meta-class 对象(元类对象)

2.instance 对象:

  • 通过[[NSObject alloc] init]创建出来的对象
  • 不同的 instance 对象占据内存不同
  • instance 对象在内存中的存储信息包括:isa指针、其他成员变量以及对应的值

3.class 对象:

  • 通过[NSObject class]创建出来的对象
  • 所有的 class 对象都是同一个对象,每个类在内存中有也只有一个 class 对象
  • class 对象在内存中的存储信息包括:isa指针、superclass指针、类的属性信息(@property)、类的对象方法信息(instance method)、类的协议信息(protocol)、类的成员变量信息(ivar)

4.meta-class 对象:

  • 通过object_getClass([NSObject class])创建处理的对象
  • meta-class对象是NSObject的元类对象,每个类在内存中也只有一个元类对象
  • meta-class对象和class对象的内存结构是一样的,但是用途不一样;
    在内存中的存储信息包括:isa指针、superclass指针、类的类方法信息(class method)
  • 注意:meta-class对象的内存结构也包括属性信息,对象方法信息等,但一般这些信息都是空的,所以可以作为忽略;
    [[NSObject class] class]获取的还是类对象,不是元类对象
  • 判断一个对象是否为元类对象,可以通过Runtime函数 class_isMetaClass([NSObject class])来判断

isa和superClass:

1. isa指针调用方法的过程:

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

《iOS 面试汇总 - OC语法》 isa指针调用方法的过程

2. superclass指针调用方法的过程:

  • 当Student的instance对象要调用Person的对象方法时,会先通过isa找到Student的class,然后通过superclass找到Person的class,最后找到对象方法的实现进行调用。
  • 当Student的class要调用Person的类方法时,会先通过isa找到Student的meta-class,然后通过superclass找到Person的meta-class,最后找到类方法的实现进行调用。

《iOS 面试汇总 - OC语法》 superclass指针调用对象方法的过程
《iOS 面试汇总 - OC语法》 superclass指针调用类方法的过程

3.总结:

  • instance的isa指向class。
  • class的isa指向meta-class。
  • meta-class的isa指向基类的meta-class。
  • class的superclass指向父类的class;
    如果没有父类,superclass指针为nil。
  • meta-class的superclass指向父类的meta-class;
    基类的meta-class的superclass指向基类的class。
  • instance调用对象方法的轨迹:
    isa找到class,方法不存在,就通过superclass找父类。
  • class调用类方法的轨迹:
    isa找meta-class,方法不存在,就通过superclass找父类。

Class的本质:

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

《iOS 面试汇总 - OC语法》 ISA_MASK

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

《iOS 面试汇总 - OC语法》 struct objc_class

    原文作者:FunkyRay迦南
    原文地址: https://www.jianshu.com/p/d934ea4e237f
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞