质量监控-图片减包

经过多个版本迭代,项目在release配置下的打包体积依旧轻松破百,应用体积过大导致的问题包括: 更长的构建时间,换个词就是加班 TEXT段体积过大会导致审核失败 用户不愿意下载应用 通常来说,资源文件能在应用体积包中占据1/3或者更多的体积,相比起代码(5kb/千行)的平均占用来说,对图片进行减包是最直接高效的手段,对图片资源的处理方式包括四种: 通过请求下载大图 使用工具压缩图片 查找删除重复图片 查找复用相似图片 考虑到由于项目开发分工的问题,方式1需要推动落地,所以本文不讨论这种处理方式。其他三种都能通过编写脚本实现自动化处理 图片压缩 图片压缩分为有损压缩和无损压缩两类,有损压缩放弃了一部分图片的质量换取更高的压缩比。网上主流的压...
Click to read more ...

分析实现-离散请求

网络层作为App架构中至关重要的中间件之一,承担着业务封装和核心层网络请求交互的职责。讨论请求中间件实现方案的意义在于中间件要如何设计以便减少对业务对接的影响;明晰请求流程中的职责以便写出更合理的代码等。因此在讲如何去设计请求中间件时,主要考虑三个问题: 业务以什么方式发起请求 请求数据如何交付业务层 如何实现通用的请求接口 以什么方式发起请求 根据暴露给业务层请求API的不同,可以分为集约式请求和离散型请求两类。集约式请求对外只提供一个类用于接收包括请求地址、请求参数在内的数据信息,以及回调处理(通常使用block)。而离散型请求对外提供通用的扩展接口完成请求 集约式请求 考虑到AFNetworking基本成为了iOS的请求标准,以传统的集约式请求代码为例: ...
Click to read more ...

开发笔记-警惕swizzling

不知道什么时候开始,只要使用了swizzling都能被解读成是AOP开发,开发者张口嘴就是runtime,将其高高捧起,称之为黑魔法;以项目中各种method_swizzling为荣,却不知道这种做法破坏了代码的整体性,使关键逻辑支离破碎。本文基于iOS界的毒瘤一文,从另外的角度谈谈为什么我们应当警惕 调用顺序性 调用顺序性是链接文章讲述的的核心问题,它会破坏方法的原有执行顺序,导致意料之外的错误。先从一段简单的代码聊起: @interface SLTestObject: NSObject @end @implementation SLTestObject - (instancetype)init { self = [super init]; return s...
Click to read more ...

分析实现-谈谈响应链

当用户的手指在屏幕上的某一点按下时,屏幕接收到点击信号将点击位置转换成具体坐标,然后本次点击被包装成一个点击事件UIEvent。最终会存在某个视图响应本次事件进行处理,而为UIEvent查找响应视图的过程被称为响应链查找,在整个过程中有两个至关重要的类:UIResponder和UIView 响应者 响应者是可以处理事件的具体对象,一个响应者应当是UIResponder或其子类的实例对象。从设计上来看,UIResponder主要提供了三类接口: 向上查询响应者的接口,体现在nextResponder这个唯一的接口 用户操作的处理接口,包括touch、press和remote三类事件的处理 是否具备处理action的能力,以及为其找到target的能力 总体来说UIR...
Click to read more ...

多线程-线程安全(二)

之前写过一篇线程安全,简单介绍了保护数据安全的多种方式,以及其中一部分方式的原理。基于此基础,本文将介绍如何避免锁的性能浪费,以及如何实现无锁安全结构 避免锁的性能浪费 为了避免多个线程对数据的破坏,在使用锁保障线程安全的情况下,存在几个影响锁性能的重要因素: 上下文切换 临界区资源耗时 如果能够减少这些因素的损耗,就能有效的提高锁的性能 自旋锁 通常来说,当一个线程获取锁失败后,会被添加到一个等待队列的末尾,然后休眠。直到锁被释放后,依次唤醒访问临界资源。休眠时会发生线程的上下文切换,当前线程的寄存器信息会被保存到磁盘上,考虑到这些情况,能做的有两点: 换一个更快的磁盘 改用自旋锁 自旋锁采用死循环等待锁释放来替代线程的休眠和唤醒,避免了上下文切换...
Click to read more ...

开发笔记-mock in iOS

在面向对象编程中,有个非常有趣的概念叫做duck type,意思是如果有一个走路像鸭子、游泳像鸭子,叫声像鸭子的东西,那么它就可以被认为是鸭子。这意味着当我们需要一个鸭子对象时,可以通过instantiation或者interface两种机制来提供鸭子对象: @interface Duck : NSObject @property (nonatomic, assign) CGFloat weigh; - (void)walk; - (void)swim; - (void)quack; @end /// instantiation id duckObj = [[Duck alloc] init]; [TestCase testWithDuck: duckObj]; /// i...
Click to read more ...

WWDC-内存策略

尽管在进入后台之后,程序的工作受到大幅度的限制,但是我们总是不会希望应用突然被操作系统杀死,中断了重要的后台工作。后台应用被杀死,影响的不止是用户体验,比如正在播放的音乐戛然而止,正在导航的语音意外中断。由于操作系统杀死后台应用并不是任何一种异常、或者运行错误,应用失去响应意外的能力,极有可能破坏了单次运行中积累的重要数据。因此如何减少应用在后台运行被杀死,是一个值得思考的问题 后台应用如何被杀 抛开因为应用在后台停留太久被杀死之外,因为内存问题被杀死是最重要的原因。内存和其他硬件资源有很大的不同,区别在于: 当资源需求量多于资源所能供应的时,CPU表现为性能下降,而操作系统会为了回收内存杀死后台应用 我们可以把设备内存分成四块区域,包括system、background...
Click to read more ...