Tagged Pointer小知识

运行下面两段代码,会发生什么事?
Tagged Pointer小知识_第1张图片

这两段代码看似一致,其实结果差别很大,代码1会崩溃(奔溃信息如下),代码2却不会;


从报错信息可以看出原因是坏内存访问,现在使用的是ARC,但是ARC的底层实现是MRC,如下:

//self.name赋值MRC实现
- (void)setName:(NSString *)name
{
    if (_name != name) {
        [_name release];
        _name = [name retain];
    }
}

由于线程不安全,多条线程同时执行了[_name release];这行代码,所以下一个线程进来的时候,发现self.name已经被释放了,那么就会出现坏内存访问的情况;

那么为什么代码2没有崩溃呢?
这是因为从64bit开始,iOS引入了Tagged Pointer技术,用于优化NSNumber、NSDate、NSString等小对象的存储,这些较小的对象,直接存储在栈区,所以线程不安全并没有影响到栈区。

arm64架构后指针有64位,于是把空余的位利用起来,存储对象值,这个就是Tagged Pointer

打印查看两字符对象的地址:


Tagged Pointer小知识_第2张图片

可以看出str2的地址明显高于str1,因为栈区的地址值,要在堆区之上,可以简易推测str2的值直接存在指针上。

详细的Tagged Pointer介绍有好多博客

深入理解Tagged Pointer

你可能感兴趣的:(Tagged Pointer小知识)