Tagged Pointer 含义的解释

一、含义

  • iOS 是在 64bit 开始,引入的 Tagged Pointer 技术
  • 用于优化 NSNumberNSDateNSString 等 小对象 的存储
    • 比如: 小型的 OC 对象,就可能用 Tagged Pointer 来实现
  • 在没有使用之前,NSNumber 等对象就是一个普通的OC 对象。需要动态分配内存、维护引用计数等,NSNumber 指针存储的是堆中 NSNumber 对象的地址值(跟其他的OC 对象没有任何区别)
    • 例如: NSNumber *number = [NSNumber numberWithInt: 10];
    • NSNumber * number = @(10);
    • NSNumber * number = @10;
    • 这三种写法 是等价的。
  • 使用之后, NSNumber 指针里面存储的数据变成了 :Tag + Data, 也就是将数据直接存储在了指针中
    • Tag : 标记,标记是 NSNumber 类型还是 NSDate 类型等
    • Data : 真正的数据
  • 当对象指针的最低有效位是1,则该指针为 Tagged Pointer
  • 当指针不够存储数据时,才会使用动态分配内存的方式来存储数据
  • Objc_msgSend 能够识别 Tagged Pointer , 比如 NSNumberintValue 方法, 直接从指针提取数据,节省了以前的调用开销。

二、解释 NSNumber 未使用 tagged Pointer 之前的内存

在这里插入图片描述

如图:NSNumber * number = @10; 是定义在 main 函数中的,所以是 局部变量。在函数中定义的局部变量放在 栈空间。
在这里插入图片描述

  • 如果 NSNumber 对象 的堆地址为 0x000001
  • 那么 栈空间内的 number 存储的就是 0x00001

存储堆内存的地址值

也就是说:如果想要将 10 这个值存储到系统中:

  • 首先要:alloc 一块 对空间
  • 在弄一个 指针变量 NSNumber *number
  • 在把 alloc 出来的堆内存空间地址给 number 指针

如果用 int 类型的话,才4个字节。但是到了 NSNumber 就这么复杂。
* int a = 10 ;

那么为什么要包装成 NSNumber 类型?

  • 因为 NSArrayNSDictionary 中不能存储 int 类型。所以只能包装成 NSNumber 类型。
  • *number 指针要8个字节
  • alloc 出来的对象最少要16个字节
  • 这样比 int 类型要多很多
  • 所以苹果 引进了 tagged Pointer 这个技术

三、解释 NSNumber 使用 tagged Pointer 之后的内存
在这里插入图片描述
这个里面,相当于只用了8个字节,就保存了 值

例如:
在这里插入图片描述

打印结果是:
0x127,0x227,0x327

在这里插入图片描述

打印结果是:
0x427,0x527,0x627

如果存储的数很大
NSNumber *number = @(0xFFFFF);
NSLog(@"%p", number);

打印结果:0x102b292d0
这个地址很明显是一个堆空间的地址

也就是说:如果 tagged pointer 8 个控件放不下的话。就变成了堆空间地址。

在这里插入图片描述

五、Objc_msgSend 能够识别 Tagged Pointer

NSNumber *number1 = @4
// 运行时是 objc_msgSend(number1, @selector(intValue))
int a =  [number1 intValue];
  • objc_msgSend(number1, @selector(intValue)) 这句话的意思大家都知道。就是:通过 number1isa 指针找到 number1 的类对象,去它的类对象里面找 intValue 方法。
  • 但是 number1 是采用tagged pointer 技术实现的。没有经过 alloc 也就没有堆空间,也不存在isa。因为 tagged pointer 就一个指针,指针里面存储的东西就是 tag + data

objc_msgSend方法里面会 进行判断,有没有使用 tagged pointer技术,如果有使用,就不会再去 拿 isa 在找东西。

  • 它会 直接把 值从 指针中抽取出来。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值