被遗弃的线程

main函数作为程序运行的入口,正常情况下,函数会执行毫秒级别的操作,然后返回一个0表示程序正常终止。为了避免应用启动即终止,苹果设计了runloop机制来维持线程的生命,runloop在每一次的循环当中不断的去处理事件,或控制线程的休眠和唤醒。runloop还结合了libdispatch的任务派发机制,可以循环地处理async到队列中的任务 启动runloop 从runloop对外暴露的接口来看,启动方式一共存在三种: 无条件的启动。这种启动方式缺少停止runloop的手段,唯一的结束方式是kill掉线程 - (void)run; 设定超时时间。直接run会调用这个接口并且传入distantFuture,表示无限长的超时...
Click to read more ...

奇怪的GCD

多线程一直是我相当感兴趣的技术知识之一,个人尤其喜爱GCD这个轻量级的多线程解决方案,为了了解其实现,不厌其烦的翻阅libdispatch的源码。甚至因为太喜欢了,本来想要写这相应的源码解析系列文章,但害怕写的不好,于是除了开篇的类型介绍,也是草草了事,没了下文 恰好这几天好友出了几道有关GCD的题目,运行结果出于意料,仔细摸索后,发现苹果基于libdispatch做了一些有趣的修改工作,于是想将这两道题目分享出来。由于朋友提供的运行代码为Swift书写,在此我转换成等效的OC代码进行讲述。你如果了解了下面两个概念,会让后续的阅读更加容易: 同步与异步的概念 队列与线程的区别 被误解的概念 对于主线程和主队列,我们可能会有这么一个理解 主线程只会执行主队列的任...
Click to read more ...

一对一设计

一对一one to one并不是某种业务上的具体需求,它仅仅是一种数据存储上的设计。one to one要求一个变量能且最多只能匹配一个变量,这听着很绕口,举个常见的结构例子就是key-value匹配。不同的编程语言提供了高层级的key-value存储结构,例如dictionary字典,被这些高层级的存储结构宠坏了的我们不知是否思考过这么一个问题: dictionary是怎么通过key来存储或者移除匹配的value的 应用程序的数据存储只存在连续存储和非连续存储这两种方式,并且非连续存储需要使用额外的内存来存储下一个数据的信息,因此非连续存储的内存开销是大于连续存储方式的。在dictionary的存储结构中,key和value可以完全不同且没有丝毫的关联性,这是否意味着字典...
Click to read more ...

倒计时设计

计算机是不存在倒计时这个概念的,所有的倒计时设计来源于对定时器的运用:给予一个deadline,以秒为时间间隔,在每次回调时刷新屏幕上的数字。倒计时的实现几乎没有门槛,无论NSTimer也好,GCD也罢,甚至使用CADisplayLink都能用来制作一个倒计时方案。但同样的,低门槛也意味着方案的上下限差也很大,本文打算谈谈如何设计一个倒计时方案 为什么要写这篇文章 事实上,倒计时和我目前开发的方向八竿子打不着,我也确实没有必要和想过写这么一套方案。只是这几天有朋友分享了别人设计的倒计时功能: 采用一个全局计时管理对象针对每一个倒计时按钮分配计时器,计时器会生成一个NSOperation对象来执行回调,完成倒计时功能 在抛开代码不谈的情况下,这套设计思路我也是存疑的。如果倒...
Click to read more ...

2017回顾

时光飞逝,转眼就到了2017的尾巴,距离踏入职场已经有2.5个年头。和去年忙于业务开发相比,今年的工作变得截然不同,在这一年里也收获了很多。正是这一年的学习,让自己发现iOS开发范围远没有想象的那么狭隘,扩展了自己的技术边界和眼界。 在今年年中之前,共从事过两家公司的正式开发职位,遗憾的虽然两家公司都是创业公司,却也没有带来网上常说的创业公司能帮助个人快速成长,在方方面面都能得到长进这一收获。于是这让我倍感焦虑,从15年移动端开发的狂热,到16年的消退潮,再到今年移动端开发的入门门槛提高,更强大的后浪不断袭来,不管是在工作经历还是开发项目上,远远称不上有亮点的自己,在未来应该何去何从。还好,年初开始接触APM这一开发方向,比起业务开发更深入的去探索iOS的深处,也成功的收获了滴滴和饿...
Click to read more ...

隐式动画的性能瓶颈

隐式动画实现的背后体现了核心动画精心设计的许多机制。在layer的属性发生改变之后,会向它的代理方请求一个CAAction行为来完成后续的工作,系统允许代理方返回nil指针。一旦这么做,修改属性的工作最终移交给CATransaction处理,由修改的属性值决定是否自动生成一个CABasicAnimation。如果满足,此时隐式动画将被触发。 关于CATransaction 在核心动画中,每个图层的修改都是事务CATransaction的一部分,它可以同时对多个layer的属性进行修改,然后成批的将将多个图层树包装起来,一次性发送到渲染服务进程。CATransaction事务对象被分为implicit和explicit两种类型,分别对应隐式和显式。implicit transactio...
Click to read more ...

野指针定位

当所指向的对象被释放或者收回,但是对该指针没有作任何的修改,以至于该指针仍旧指向已经回收的内存地址,此情况下该指针便称野指针 野指针异常堪称crash界的半壁江山,相比起NSException而言,野指针有这么两个特点: 随机性强 尽管大公司已经有各种单元、行为、自动化以及人工化测试,尽量的去模拟用户的使用场景,但野指针异常总是能巧妙的避开测试,在线上大发神威。原因绝不仅仅在于测试无法覆盖所有的使用场景 造成野指针是多样化的:首先内存被释放后不代表内存会立刻被覆写或者数据受到破坏,这时候访问这块内存也不一定会出错。其次,多线程技术带来了复杂的应用运行环境,在这个环境下,未加保护的数据可能是致命的。此外,设计不够严谨的代码同样也...
Click to read more ...