前言

这篇博客九月就想写了,因为赶项目拖了到现在,抓住17年尾巴写吧~

正文

上次看了一篇 《从一道网易面试题浅谈OC线程安全》 的博客,主要内容是:

作者去网易面试,面试官出了一道面试题:下面代码会发生什么问题?

@property (nonatomic, strong) NSString *target;
//....
dispatch_queue_t queue = dispatch_queue_create("parallel", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 1000000 ; i++) {
dispatch_async(queue, ^{
self.target = [NSString stringWithFormat:@"ksddkjalkjd%d",i];
});
}

答案是:会 crash。

我们来看看对target属性(strong修饰)进行赋值,相当与 MRC 中的

- (void)setTarget:(NSString *)target {
if (target == _target) return;
id pre = _target;
[target retain];//1.先保留新值
_target = target;//2.再进行赋值
[pre release];//3.释放旧值
}

因为在 并行队列 DISPATCH_QUEUE_CONCURRENT异步 dispatch_asynctarget属性进行赋值,就会导致 target 已经被 release了,还会执行 release。这就是向已释放内存对象发送消息而发生 crash 。

但是

我敲了这段代码,执行的时候发现并不会 crash~

@property (nonatomic, strong) NSString *target;
dispatch_queue_t queue = dispatch_queue_create("parallel", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 1000000 ; i++) {
dispatch_async(queue大专栏  从一道网易面试题浅谈 Tagged Pointer - darcy_tang 的博客n class="p">, ^{
// ‘ksddkjalkjd’删除了
self.target = [NSString stringWithFormat:@"%d",i];
});
}

原因就出在对 self.target 赋值的字符串上。博客的最后也提到了 - ‘上述代码的字符串改短一些,就不会崩溃’,还有 Tagged Pointer 这个东西。

我们将上面的代码修改下:

NSString *str = [NSString stringWithFormat:@"%d", i];
NSLog(@"%d, %s, %p", i, object_getClassName(str), str);
self.target = str;

输出:

0, NSTaggedPointerString, 0x3015

发现这个字符串类型是 NSTaggedPointerString,那我们来看看 Tagged Pointer 是什么?

Tagged Pointer

Tagged Pointer 详细的内容可以看这里 深入理解Tagged Pointer

Tagged Pointer 是一个能够提升性能、节省内存的有趣的技术。

  • Tagged Pointer 专门用来存储小的对象,例如 NSNumberNSDate(后来可以存储小字符串)
  • Tagged Pointer 指针的值不再是地址了,而是真正的值。所以,实际上它不再是一个对象了,它只是一个披着对象皮的普通变量而已。
  • 它的内存并不存储在堆中,也不需要 malloc 和 free,所以拥有极快的读取和创建速度。

参考:


从一道网易面试题浅谈 Tagged Pointer - darcy_tang 的博客的更多相关文章

  1. 如何用一个语句判断一个整数是不是二的整数次幂——从一道简单的面试题浅谈C语言的类型提升(type promotion)

    最近招聘季,看JULY大哥的面试100题时,碰到这么一个扩展问题: 如何用一个语句判断一个整数是不是二的整数次幂?(此题在编程之美也有) easy, 2的整数次幂的二进制形式只有一个1,只要用i和i- ...

  2. 通过一道笔试题浅谈javascript中的promise对象

    因为前几天做了一个promise对象捕获错误的面试题目,所以这几天又重温了一下promise对象.现在借这道题来分享下一些很基础的知识点. 下面是一个面试题目,三个promise对象捕获错误的例子,返 ...

  3. 面试题-浅谈JavaScript中的This指向问题

    各位小伙伴在面试中被面试官问道this指向问题一定不少吧,同时还被问道apply,call和bind的用法区别,现在,就来简单的聊一聊this到底指向何方. 1.基本概念 MDN的官方解释:与其他语言 ...

  4. 产品经理面试题——浅谈O2O

    分析:O2O也要分种类.      现在的O2O 已经是线上线下相互融合的阶段了,无论是线上体验,线下消费还是线下体验,线上下单.都已有比较成熟的模式.我对O2O的理解就是以消费者为中心,整合线上和线 ...

  5. 100个iOS开发面试题汇总-王刚韧的技术博客

    100个iOS开发面试题汇总 关于iOS开发面试,不管对于招聘和应聘来说,面试都是很重要的一个环节,特别对于开发者来说,面试中的技术问题环节不仅是企业对应聘者技能和积累的考察,也是一个开发者自我检验的 ...

  6. [2009国家集训队]小Z的袜子(hose) 浅谈莫队

    浅谈莫队 推荐学习博客 http://foreseeable97.logdown.com/posts/158522-233333 借用题目: bzoj 2038 2009 国家集训队 小Z的袜子htt ...

  7. [随机化算法] 听天由命?浅谈Simulate Anneal模拟退火算法

    Simulate Anneal模拟退火算法,是一种用于得到最优解的随机化算法. 如果可以打一手漂亮的随机化搜索,也许当你面对一筹莫展的神仙题时就有一把趁手的兵器了. 这篇题解将教你什么?SA的基本思路 ...

  8. 浅谈web应用的负载均衡、集群、高可用(HA)解决方案(转)

    1.熟悉几个组件 1.1.apache     —— 它是Apache软件基金会的一个开放源代码的跨平台的网页服务器,属于老牌的web服务器了,支持基于Ip或者域名的虚拟主机,支持代理服务器,支持安 ...

  9. 浅谈web应用的负载均衡、集群、高可用(HA)解决方案

    http://aokunsang.iteye.com/blog/2053719   声明:以下仅为个人的一些总结和随写,如有不对之处,还请看到的网友指出,以免误导. (详细的配置方案请google,这 ...

随机推荐

  1. ZJNU 1422 - 碰撞的小球

    完全弹性碰撞可以视作互相穿过 所以直接考虑只有单个小球的时候,从板子上滑下所需要的时间即可 最后以30000为界分开流读入与缓冲区优化的io方法 //Case4用缓冲区io优化会WA??? /* Wr ...

  2. [NOI2014]魔法森林(LCT)

    蒟蒻又发现自己还没写过LCT…… 首先显然按照权值a从小到大排序,维护b的最小生成树.然后直接扫,代价是加入b的最大值,然后动态加边,因为有边权,所以在lct中边应该理解为点.每次连接(u,v)时,若 ...

  3. 注册服务和发现服务 Eureka

    来自蚂蚁课堂: 注册服务和发现服务 1.原理如图: 注册中心负载均衡: 实践 注册中心 集群:

  4. Python笔记_第二篇_面向过程_第二部分_3.模块的概述

    这部分内容是非常重要的,分模块的基本概念和一些常用模块的使用,其实常用模块使用这部分也不是太全面,后续或者有机会再通过其他材料进行讲解. 1. 模块的概述: 目前代码比较少,写在一个文件中还体现不出什 ...

  5. Nginx模块-ngx_http_mirror_module-流量复制

    参考1:https://www.cnblogs.com/cjsblog/p/12163207.html Nginx流量复制 需求 将生产环境的流量拷贝到预上线环境或测试环境,这样做有很多好处,比如: ...

  6. 关于tomcat报错记录

    启动报错关键信息如下: Caused by: java.lang.IllegalStateException: Unable to complete the scan for annotations ...

  7. 绿洲作业第二周 - 周二music work 音乐

    Please kindly find the music work from Ms. Sophie. 1.请跟随附件中老师录制的视频进行学习和练习.(附件有带拼音的乐谱供KS1和外国学生使用) htt ...

  8. spark mllib lda 中文分词、主题聚合基本样例

    github https://github.com/cclient/spark-lda-example spark mllib lda example 官方示例较为精简 在官方lda示例的基础上,给合 ...

  9. linux c 调用 so 库

    /***********编译时要链接 -l dl 库************/ #include<stdlib.h> #include<stdio.h> #include< ...

  10. CentOS7离线安装MySQL8.0

    CentOS7离线安装MySQL8.0 卸载软件 rpm -e --nodeps 要卸载的软件包 root@jacky zookeeper]# rpm -e --nodeps java-1.6.0-o ...