>

第七章

去年今日此门中,人面桃花相映红。人面不知何处去,桃花依旧笑春风。

iOS APP内存优化记录

APP在运行过程中,如果内存占用过高则会引起以下几个问题:

①被操作系统的守护进程给杀掉,无论是前台还是后台;

②耗电增大,手机发热;

③系统可能会运行卡顿(不是换入换出到磁盘,而是解压缩和重压缩内存);

业务背景

因为我们APP的直播间要玩网页版的小游戏,比较耗内存,除了JS游戏本身降低内存消耗之外,native也需要释放更多的内存以提供给游戏使用,避免因为内存占用过大而被操作系统杀掉进程。

优化native本身的内存占用大体分为两部分:优化长期的内存占用和优化峰值内存占用。

iOS知识结构

计算机三大知识结构:数据结构和算法,网络,操作系统。

这里陈硕在知乎上有个补充:https://www.zhihu.com/question/21405835,主要是谈到了计算机体系结构,这一块涉及到各个层面知识的串联和整合。

本文不会讲的很详细,只是简单罗列一些知识点及其应用场景,具体怎么做不会展开。

主要分几块的内容:iOS开发相关,计算机知识结构,软实力和职业规划。

崩溃和卡顿

本文尝试分析和总结一下崩溃和主线程卡顿(ANR)的原理,以及对应的部分解决方案和案例。

《深入解析Mac OS X & iOS操作系统》

整体上还算不错,对内核,Mach和BSD的介绍,包括一些函数和调用等,以及对异常处理的描述,对于理解PLC这个崩溃日志生成的库还是很有帮助的。同时一些内核线程、用户线程的概念也算是填补部分知识空白。引导过程虽然讲的很详细,不过兴趣不大。

《现代操作系统》

非常棒的一本书,可以把很多知识点给串起来,对于操作系统的历史发展和基本运行规则有比较清晰的描述。对非计算机科班的孩纸特别友好。个人认为第二章进程和线程,第三章存储管理,第六章死锁,第十章Linux实例研究都是非常值得读的章节,对实际理解操作系统也非常有用。当然如果涉及到视频,第七章的多媒体也不错。

存储管理这一章有一个小节介绍了很多种页面置换算法,在实际应用中,iOS很多第三方的框架有用到,比如YYCache用的LRU算法。

PLCrashreporter源码分析其二

本篇文章主要对PLC内部用到的一些当时看源码时不太理解的底层函数进行分析,以及对一些为了理解PLC的原理需要了解的概念进行汇总。

PLCrashreporter源码分析其一

大概总共会分三篇文章来分析PLC,第一篇讲整体的工作流程,第二篇梳理PLC内部使用到的一些特殊函数的含义,第三篇会尝试做一个实践。

不定期更新,我想明白PLC的某个细节可能就会来更新一下。

腾讯体育iOS客户端逆向实践

最终实现的结果:

可以跳过闪屏+直播间广告,如果是免费的比赛,或者你是会员的话,可以提取直播间的超清直播URL(蓝光画质是服务器鉴权),该URL可以复制到手机Safari或者电脑端播放。

实践总结:

1.所有拉流直播链接都是服务器鉴权的,即使免费的比赛,你未登录时也会给你分配一个key;

2.一个普通非会员账号,是可以蹭几场会员才能看的比赛的,但是因为腾讯体育的服务器对同个账号的拉流有IP数量限制和流量限制,所以一般说来,除非是免费的比赛,否则不要把链接扩散给别人,另外就是蹭了几场比赛后,你的账号拿到的拉流URL,将只能试看1分钟,之后被断流。腾讯体育支持微信和QQ登录,你也可以准备多个账号用来救急某些重要比赛,当然还是买会员支持正版比较直接啦;

3.会员才能看的比赛,非会员也有一个方式可以看直播,清晰度一般但是勉强能看。还是买会员看蓝光画质美滋滋

4.直播间获取直播链接的接口前缀为:http://info.zb.video.qq.com/,后面会拼接很多的参数,其中一个key跟用户账号绑定,服务器用这个来做ip打击和流量控制,抓包请认准该接口,返回数据为json格式,未做二次加密。在腾讯体育APP里,这个请求是用NSURLConnection这个类发出去的,要hook的话也要hook这个类的网络请求,而不是NSURLSession

5.腾讯体育的直播拉流协议使用HLS,你用Charles抓包会看到ts文件不断的被下载下来播放。

FFExtension

写这个库的初衷是为了防止一些常见的崩溃,扫了一圈github上已有的库,都不太合适,像avoidCrash虽然能用,但是我不喜欢它用try-catch来做防崩溃的方式,它GitHub上的issue页也有很多问题是不好去定位和解决的。所以决定自己来是实现一遍。仓库的GitHub地址,使用过程中遇到任何问题欢迎issue。

主要原理就是用Method Swizzle去hook系统类包括私有类的函数, 对常见的容器类,数组字典字符串这些有做保护,顺带新增了 NSSet,NSCache,NSUserDefaults,NSData ,NSAttributedString等几个类的保护,支持拦截 unrecognized selector sent to instance 异常,设置好要拦截的类即可。

一些使用代码规范就能解决的崩溃,比如 NSTimer,通知和 KVO 等等,本项目并未做额外处理,这种低级的失误,还是用代码规范来限制比较好。

已经在自己的项目用上了,目前工作稳定,iOS8.x 到 iOS12 都测试通过。

iOS启动时间优化

背景

一个项目做的时间长了,启动流程往往容易杂乱,库也用的越来越多,APP的启动时间也会慢慢变长。本次将针对iOS APP的启动时间优化一波。

通常针对一个技术点做优化的时候,都要先了解清楚这个技术点有哪些流程,优化的方向往往是减少流程的数量,以及减少每个流程的消耗。

本次优化从结果上来看,main阶段的优化效果最显著,尤其是启动时的一些IO操作处理,对启动时间的减少有很大作用。多线程启动的设计和验证最有意思,但是在实践上由于我们业务本身的原因,只开了额外一个子线程来并行启动,且仅在子线程做了少量的独立操作,这个要根据不同的业务去具体分析了。

一般说来,pre-main阶段的定义为APP开始启动到系统调用main函数这一段时间;main阶段则代表从main函数入口到主UI框架的viewDidAppear函数调用的这一段时间。(本文后续main阶段的时间统计都用viewDidAppear作为基准而非的applicationWillFinishLaunching

本文前半部分讲原理(内容基本是从网上借鉴/摘录),后半部分讲实践,pre-main阶段的原理比较难理解,不过实践倒是根据结论直接做就好了。

#