ios中有一种结构叫做TaggedPointer,这是设备从32位升级到64位后的一种优化措施,能够大幅度减少小对象的内存占用问题,例如:NSDate,NSNumber,NSString等
TaggedPointer结构简介
这里的TaggedPointer结构是LSB下的,标记位在尾处,8字节64位,如下图所示(MSB原理和其类似,不多介绍):
平时储存对象指向的内容为:地址+数据, 由于是小对象类型,将其改成上面的通过 标记+数据 的格式直接进行存取(系统还加入了部分安全处理来编码解码,这里不考虑)
可以看到,在结尾处最后一位,表示是否存放的是TaggedPoiner类型,如果是,紧挨着的三位tagindex存放的是类型等标记,如果tagIndex放满了(一共3位),当tagIndex为111时,会引出下面的扩展标记位继续使用,
payload空间就用来存放小数据,例如:int、bool、float、date、小字符串等数据
注意:由于taggedpointer比较小,内容均保存在指针里,因此不需要在堆区分配空间,他会普通的数字一样,只不过是指针(保存了对象信息的指针),在对象之间传递罢了,因此不需要retain和release,索引retain就是赋值,release什么申请也没干
taggedPointer结构比较简单,重点就介绍到这里
内存优化
通过TaggedPointer,可以看到位运算在内存优化上重要性,下面介绍下常用的位运算
位运算:计算机中的数字字符串都是以0、1储存的,位运算就是在其基础上进行的
例如:int a = 12, int类型 共4字节或32位,因此计算机中二进制表示为 -- 00000000 00000000 00000000 00001100,位运算就是在这个二进制基础上进行的
位运算的基本操作
& 按位与(两边对应位都是1则1,否则0) 11110101 & 00111010 = 00110000
| 按位或(两边对应位有1则1,否则0) 11110101 & 00111010 = 11111111
~ 按位取反(0变1,1变0) 11110101 - 00001010
<< 算术左移(与逻辑左移一样,不涉及符号位) 10000111000
>> 算术右移(带符号位的右移,最高位补充符号位) 11110101 >> 3 = 11111110
>>> 逻辑右移(无符号右移) 11110101 >> 3 = 00011110
^ 异或(两个相同0不同位1) 11110101 ^ 00111010 = 11001111
同或(两个相同1不同位0,没有同或符号,可以先取反在异或)
用移位交换两个数据
交换a、b
a = 1010 0001
b = 0000 1100
a = a^b //a = 1010 1101 -- 1010 1101 a = 原a ^ 原b
b = a^b //b = 0000 1100 -- 1010 0001 b = a ^ 原b = 原a ^ 原b ^ 原b = 原a
a = a^b //实现了交换 a = 0000 1100 a = a^b = 原a ^ 原b ^ 原a = 原b
最后
尝试下使用位运算实现一些其他功能吧(PS:例如:结合实现细胞存活的生命游戏算法)