我们可以将一个对象的指针拆成两部分,一部分直接保存数据,另一部分作为特殊标记,表示这是一个特别的指针,不指向任何一个地址。所以,引入了Tagged Pointer对象之后,64位CPU下NSNumber的内存图变成了以下这样:
Tagged Pointer
测试
#import
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSNumber *number1 = @1;
NSNumber *number2 = @2;
NSNumber *number3 = @3;
NSNumber *numberFFFF = @(0xFFFF);
NSNumber *numberLager = @(MAXFLOAT);
NSLog(@"number1 pointer is %p", number1);
NSLog(@"number2 pointer is %p", number2);
NSLog(@"number3 pointer is %p", number3);
NSLog(@"numberLager pointer is %p", numberLager);
/*
2017-03-10 12:07:50.731726 TaggedPoint[1690:50438] number1 pointer is 0x127
2017-03-10 12:07:50.731992 TaggedPoint[1690:50438] number2 pointer is 0x227
2017-03-10 12:07:50.732011 TaggedPoint[1690:50438] number3 pointer is 0x327
2017-03-10 12:07:50.732043 TaggedPoint[1690:50438] numberLager pointer is 0x1002006a0
*/
}
return 0;
}
以 0x127 为例 去掉 tag27(假设27为标记) 0x1 就是number 的值。
0x227
0x327
都有这种规律
numberLager 存储的值为MAXFloat 显然超过了tagged pointer 可以存储的范围。
所以打印的地址是单纯的指针地址,指向存储numberLager的内存地址。











