美文网首页
Tagged Pointer

Tagged Pointer

作者: 人仙儿a | 来源:发表于2017-11-28 14:42 被阅读24次

    NSNumber

    因为在从32位升级到64位后,同一个对象占用的内存会变成原来的2倍,为了节省内存和访问效率而引入了TaggedPointer. 像NSNumber,NSDate的地址不是真正的地址,如果是NSNumber@(1),@(2),那么地址分别是是

    (__NSCFNumber *) $0 = 0xb000000000000012 (int)1
    (__NSCFNumber *) $3 = 0xb000000000000022 (int)2
    

    我们发现倒数第2位就是存储的真实值,它会以0xb......2这样的格式展示,指针包含两部分,一部分是真实值,一部分是特殊标记。但是这样的话,如果数值过大,位数就不够了。我们测试一下,我们用一个特别大的值,@(0xEFFFFFFFFFFFFFFF),地址是:

    (__NSCFNumber *) $5 = 0x00006000000320e0 
    

    结果很像一个指针,这个是真正的指针,它没有用到TaggedPointer。

    ISA失效

    虽然taggedPointer有一定的好处,但是它并不是一真正的对象,而是个伪对象,所以我们不能直接获取它的isa,否则就会报错。为了获取Isa,我们定义一个假的tempObject结构体来抽取isa指针:

        struct tempObject {
            Class isa;
        };
        ViewController *vc = [[ViewController alloc] init];
        struct tempObject *oo = (__bridge struct tempObject *)number;
        Class isa = oo->isa;
    

    结果运行时报错,访问了野指针:

    Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    

    说明它根本就没有isa指针。但是如果我们用object_getClass()[NSNumber Class]来获取isa时会返正确的的Class:__NSCFNumber。因为苹果已经伪装好了,很多runtime API里都会判断是否是TaggedPointer对象,会对它单独进行处理。

    相关文章

      网友评论

          本文标题:Tagged Pointer

          本文链接:https://www.haomeiwen.com/subject/pntebxtx.html