质量监控-监控启动崩溃

相较于正常的崩溃问题,启动crash造成的损失要远远大得多。正常来说,如果有足够强健的构建发布系统,大多数时候能在版本上线之前及时发现问题并且修复,但是仍然存在小概率的线上意外。启动crash一般同时具备损害严重以及难以捕获两大特点 启动过程 从应用图标被用户点击开始,直到应用可以开始响应发生了很多事情。正常来说,尽管我们希望crash监控工具启动的尽可能早,但接入方往往总是等到launch事件之后才能启动工具,而在这个时间之前发生的崩溃就是启动crash,下面列出了在应用直到launch时,存在的可能发生启动crash的阶段: 其中initialize的顺序可能在更早,但总是会在load和launch之间。从图中来说,如果我们想要监控启动crash,那么开始监控的时间点必须要...
Click to read more ...

多线程-被遗弃的线程

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 ...