iOS 底层原理

Tagged Pointer

2019-12-03  本文已影响0人  和风细羽
NSNumber * number = [[NSNumber alloc] initWithInt:11];

普通对象要在堆区开辟 16 个字节来存储 ‘11’ 这个值,在栈区 8 个字节保存堆区地址,一个简单的 int 数值,原本最多只需要 4 个字节,结果至少占了 24 个字节,并且还有维护对象引用计数,释放内存等开销。

Tagged Pointer 技术将指针的值(8个字节)进行拆分,一部分表示数据,一部分用来表示这是一个特殊的指针。

TaggedPointer 极大的提高了内存利用率和简化了查询步骤。它不单单是一个指针,还包括了其值+类型,节省了对象的查询流程。

查看真实的地址

extern uintptr_t objc_debug_taggedpointer_obfuscator;

@implementation TestTaggedPointer

/**
  *  @brief   与系统的解码方法只是名称不同,内容一致
  *  @see   objc-internal.h   _objc_decodeTaggedPointeraa() 方法
  */
uintptr_t _objc_decodeTaggedPointer_(const void * _Nullable  ptr) {
    return (uintptr_t)ptr ^ objc_debug_taggedpointer_obfuscator;
}


+ (void)test
{    
    int     num1 = 15;
    float   num2 = 11;
    double  num3 = 10;
    long    num4 = 8;
    
    NSNumber * number1 = @(num1);
    NSNumber * number2 = @(num2);
    NSNumber * number3 = @(num3);
    NSNumber * number4 = @(num4);
    
    NSLog(@"number1 = %@ - %p - 0x%lx", object_getClass(number1), &number1, _objc_decodeTaggedPointer_((__bridge const void * _Nullable)(number1)));
    NSLog(@"number2 = %@ - %p - 0x%lx", object_getClass(number2), &number2, _objc_decodeTaggedPointer_((__bridge const void * _Nullable)(number2)));
    NSLog(@"number3 = %@ - %p - 0x%lx", object_getClass(number3), &number3, _objc_decodeTaggedPointer_((__bridge const void * _Nullable)(number3)));
    NSLog(@"number4 = %@ - %p - 0x%lx", object_getClass(number4), &number4, _objc_decodeTaggedPointer_((__bridge const void * _Nullable)(number4)));

    // number1 = __NSCFNumber - 0x7ffeefbff598 - 0xf27
    // number2 = __NSCFNumber - 0x7ffeefbff590 - 0xb47
    // number3 = __NSCFNumber - 0x7ffeefbff588 - 0xa57
    // number4 = __NSCFNumber - 0x7ffeefbff580 - 0x837
    
    NSNumber * number5 = [[NSNumber alloc] initWithInt:9];
    NSLog(@"number5 = %@ - %p - 0x%lx", object_getClass(number5), &number5, _objc_decodeTaggedPointer_((__bridge const void * _Nullable)(number5)));

    // number5 = __NSCFNumber - 0x7ffeefbff578 - 0x927
    
    //0xf27、0xb47、0xa57 这些是真实的地址
}

@end

从上面的真实地址可以做一些猜测:

以上只是简单的、杂乱的记录些知识点,详细的查看下面的链接

详细文章

kwdx - TaggedPointer
fanglaoda - 你不知道的TaggedPointer

上一篇 下一篇

猜你喜欢

热点阅读