iOS tagged pointer

iOS tagged pointer

从 64bit 开始,苹果引入了 tagged pointer 计数,用于优化 NSNumber , NSDate , NSString 等小对象的存储,没有这个数据之前,NSNumber 等对象需要动态分配内存,维护引用计数,NSNumber 指针存储的是堆中NSNumber对象的地址值,而引入了这个计数之后,NSNumber 指针里面存储的数据是 : tag + data ,也就是直接将数据存储在指针中。这样做特别节省空间。如果这个数据特别大,指针存储不下这个数,那么会回复之前的方式,存储在堆区,然后指针存放堆区的地址。

dispatch_queue_t queue = dispatch_get_global_queue(0, 0 );
    for (int i = 0 ; i < 10000; i ++) {
        dispatch_async(queue, ^{
            self.name = [NSString stringWithFormat:@"%@",@"123sdfasfdas"];
        });
    }

上面会发生什么呢?答案是可能崩溃,因为我们是多线程同时方位name的set方法,那么的set方法好比


-(void)setName:(NSString *)name{
    if (_name != name) {
        [_name release];
        _name = [name copy];
    }
}

好比这样,多个线程有可能同时去 release,所以会崩溃

解决方案,可以加锁,在name设置前后去加锁。

如果改成这样呢?


dispatch_queue_t queue = dispatch_get_global_queue(0, 0 );
    for (int i = 0 ; i < 10000; i ++) {
        dispatch_async(queue, ^{
            self.name = [NSString stringWithFormat:@"%@",@"123"];
        });
    }
    

就是把一个长字符串变成一个短的字符创,这时候发现,没有崩溃。因为后一个指针为 tagged pointer 类型的,就不存在release的操作,值直接就存储再来指针的里面,直接取值就可以了,所以就不会崩溃,他就不是一个OC对象。


 NSString *str = [NSString stringWithFormat:@"123"];
    NSString *str1 = [NSString stringWithFormat:@"aefasfasdfasfdasf"];
    NSLog(@"%@  %@",[str class],[str1 class]);


我们来打印下两个类


 NSTaggedPointerString  __NSCFString

可以看到 第一个类为 tagged pointer 类,也证明了我们的猜想。

其实源码里面是有判断的,当为mac 的时候 &1,当为ios的时候&(1<<63),所以 ios 最高有效位为1就为 tagged pointer 类型,mac 最低有效位为1就为tagged pointer

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 这篇文章是参考很多资料才写出来的,有部分内容这几位写的都很详细到位,所以就直接拷贝了,这里向这几位作者学习:深入理...
    晨寂阅读 11,981评论 3 25
  • Tagged Pointer 介绍 苹果对于Tagged Pointer特点的介绍: Tagged Pointer...
    Q14阅读 3,276评论 0 0
  • Tagged Pointer是什么 我们知道,通常情况下,定义一个变量所占用的内存是与CPU的位数有关,比如NSI...
    米嘉勒阅读 4,513评论 1 3
  • 一. 内存区域 验证上图,代码如下: 运行后,整理打印: 可以发现: 上面的内存地址从小到大。 字符串常量一样的时...
    Imkata阅读 3,971评论 1 2
  • 大鱼的心路 忽如一阵大雨 大鱼 救赎 大愚 如一台压路机 碾平一路坑洼 心路坦荡 一生无涯 (在小说《大鱼》​的阅...
    安徽江美琳阅读 780评论 0 1