1. OC语法

总结

  • 结构体内存对齐: 结构体内存的大小必须是最大成员内存大小的倍数
  • 操作系统有分配内存对齐的概念(Bucket Size), 大都以16个字节为单位对齐
  • 在iOS堆空间中分配内存的话都是16的倍数,也就是说iOS堆内存中最小内存的大小为16, 这样对于操作系统访问CPU是最优最快的。(如果结构体的成员变量只需要24个字节就够用,而iOS中分配堆内存大小是32个字节)
  • class_getInstanceSize( )返回某个类对象至少需要多少空间
  • malloc_size()返回的是实例对象实际分配的内存空间

一、面向对象

1.1 Objective-C的本质

  • 我们平时编写的Objective-C代码,底层实现其实都是C\C++代码
    在这里插入图片描述

  • 所以Objective-C的面向对象都是基于C\C++的数据结构实现的

  • 思考:Objective-C的对象、类主要是基于C\C++的什么数据结构实现的?

    • 结构体
  • 将Objective-C代码转换为C\C++代码

    xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 输出的CPP文件 
    
    • 如果需要链接其他框架,使用-framework参数。比如-framework UIKit

1.2 OC对象的本质

  • 思考:一个OC对象在内存中是如何布局的?
  • NSObject的底层实现在这里插入图片描述
  • 一个普通类的底层实现
    在这里插入图片描述
    在这里插入图片描述
  • 思考:一个Person对象、一个Student对象占用多少内存空间?
    在这里插入图片描述

1.3 实时查看内存数据

  • Debug -> Debug Workfllow -> View Memory (Shift + Command + M)
  • 也可以使用LLDB指令
    在这里插入图片描述

1.4 2个容易混淆的函数

  • 创建一个实例对象,至少需要多少内存?
#import <objc/runtime.h>
class_getInstanceSize([NSObject class]);
  • 创建一个实例对象,实际上分配了多少内存?
#import <malloc/malloc.h>
malloc_size((__bridge const void *)obj);

二、常用LLDB指令

  • print、p : 打印

  • po : 打印对象

  • 读取内存

memory read/数量格式字节数 内存地址 
x/数量格式字节数 内存地址
x/3xw 0x10010
  • 修改内存中的值
memory write 内存地址 数值 
memory write 0x0000010 10
  • 格式

    • x是16进制,f是浮点,d是10进制
  • 字节大小

    • b : byte 1字节,
    • h : half word 2字节
    • w : word 4字节,
    • g : giant word 8字节

三、OC对象的分类

  • Objective-C中的对象,简称OC对象,主要可以分为3种
    • instance对象(实例对象)
    • class对象(类对象)
    • meta-class对象(元类对象)

3.1 instance

  • instance对象就是通过类alloc出来的对象,每次调用alloc都会产生新的instance对象
NSObject *object1 = [[NSObject alloc] init];
NSObject *object2 = [[NSObject alloc] init];
  • object1、object2是NSObject的instance对象(实例对象)

  • 它们是不同的两个对象,分别占据着两块不同的内存

  • instance对象在内存中存储的信息包括

    • isa指针
    • 其他成员变量
  • Person对象

@interface MJPerson : NSObject {
	@public
    int _age;
}
@end
  • Person对象使用
MJPerson *p1 = [[MJPerson alloc] init];
p1->_age = 3;

MJPerson *p2 = [[MJPerson alloc] init];
p2->_age = 4;

在这里插入图片描述

3.2 class

  • objectClass1 ~ objectClass5都是NSObject的class对象(类对象)
  • 它们是同一个对象。每个类在内存中有且只有一个class对象
ClassobjectClass1 = [object1 class];
Class objectClass2 = [object2 class];
Class objectClass3 = object_getClass(object1); // Runtime API
Class objectClass4 = object_getClass(object2); // Runtime API
Class objectClass5 = [NSObject class];
  • class对象在内存中存储的信息主要包括
    • isa指针
    • superclass指针
    • 类的属性信息(@property)、类的对象方法信息(instance method)
    • 类的协议信息(protocol)、类的成员变量信息(ivar)

    • 在这里插入图片描述

3.3 meta-class

Class objectMetaClass = object_getClass(objectClass5);
  • objectMetaClass是NSObject的meta-class对象(元类对象)

  • 每个类在内存中有且只有一个meta-class对象

  • meta-class对象和class对象的内存结构是一样的,但是用途不一样,在内存中存储的信息主要包括

    • isa指针
    • superclass指针
    • 类的类方法信息(class method)

    • 在这里插入图片描述

3.4 注意

  • 以下代码获取的objectClass是class对象,并不是meta-class对象
Class objectMetaClass2 = [[[NSObject class] class] class];

3.5 查看Class是否为meta-class

#import <objc/runtime.h>

BOOL result = class_isMetaClass([NSObject class]);

四、isa 和 superclass

4.1 isa指针

在这里插入图片描述

  • instance的isa指向class

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

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

4.2 class对象的superclass指针

在这里插入图片描述

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

4.3 isa、superclass总结

  • instance的isa指向class

  • class的isa指向meta-class

  • meta-class的isa指向基类的meta-class

  • class的superclass指向父类的class p 如果没有父类,superclass指针为nil

  • meta-class的superclass指向父类的meta-class p 基类的meta-class的superclass指向基类的class

  • instance调用对象方法的轨迹

    • isa找到class,方法不存在,就通过superclass找父类
  • class调用类方法的轨迹

    • isa找meta-class,方法不存在,就通过superclass找父类

在这里插入图片描述

五、Class的结构

5.1 isa指针

  • 从64bit开始,isa需要进行一次位运算,才能计算出真实地址
    在这里插入图片描述
    在这里插入图片描述

5.2 objc4源码下载

5.3 窥探struct objc_class的结构

  • class、meta-class对象的本质结构都是struct objc_class
    在这里插入图片描述
    在这里插入图片描述

5.4 objc_getClass和object_getClass的区别

  1. Class objc_getClass(const char *aClassName)
    1> 传入字符串类名
    2> 返回对应的类对象

  2. Class object_getClass(id obj)
    1> 传入的obj可能是instance对象、class对象、meta-class对象
    2> 返回值

    • a) 如果是instance对象,返回class对象
    • b) 如果是class对象,返回meta-class对象
    • c) 如果是meta-class对象,返回NSObject(基类)的meta-class对象
  3. - (Class)class、+ (Class)class
    1> 返回的就是类对象

- (Class) {
    return self->isa;
}

+ (Class) {
    return self;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值