这周公众号发布的如下文章:前端
本期知识小集的主要内容包括:ios
做者: halohilygit
圆角效果:圆角效果的优化老生常谈,产生性能问题的根源在于原生圆角效果带来的离屏渲染开销。一般咱们推荐直接使用圆角的素材,或者提早在子线程将图片进行圆角裁剪,这二者原理相同。除此以外,还有一种思路是在须要圆角的视图最上层添加一个中空的圆角遮罩层,以此来作出圆角效果。这个遮罩层和被盖在下面的视图在显示时会由 GPU 进行图层混合,而图层混合的开销远小于离屏渲染。值得一提的是,因为圆角效果一般在一屏中频繁出现,因此这个遮罩的图片素材能够只加载一次,而且应用于每个圆角视图,避免重复加载。github
阴影效果:值得注意的是系统原生的阴影实现要求 layer 的 masksToBounds
值为 YES,因此原生的阴影效果和圆角是不兼容的。高效的阴影实现是为阴影指定 shadowPath,若是你还没用的话,不妨试一下。web
适时替换轻量控件:@ibireme
在他的性能优化文章中提出在合适的时候用 CALayer 替换 UIView,这确实有效,不过盲目替换每每会形成代码维护的困难。这里举两个适合的场景:绘制线条时,彻底能够替换。以及静态展现图片时,将图片对象赋值给 layer 的 content 属性,也彻底能够达到效果。算法
图片解码:图片解码的知识再也不赘述,值得一提的是,对于不一样的图片格式,不一样的解码算法,或者使用系统解码方法时的不一样参数设置,都会影响解码性能,若是有这方面瓶颈的,不妨作多种尝试。小程序
再说一个经典的例子:为了实现一个简单的画板需求,有人会在 UIView 上频繁调用 drawRect
方法进行新笔划的绘制,却不知有一个天生的专用图层对象 CAShapeLayer
是很适合作这件事的。CAShapeLayer 不须要像普通 CALayer 同样建立寄宿图,不会形成巨量内存的使用,而且它使用了硬件加速。数组
UI 性能优化时,咱们经常须要实时监测帧率。这里讲一下 @ibireme
的帧率监测工具 YYFPSLabel
的实现原理:使用 CADisplayLink,在每帧的回调事件中,计数器 c 加一,而且累计时间间隔 t 也进行更新。当时间间隔够 1 秒后,使用 c/t 计算出过去 1 秒的帧率,然后计数器清零,时间戳更新为当前时间戳,再重复以前步骤。所以 YYFPSLabel 的帧率更新周期在 1 秒左右。缓存
做者: Lefe_x安全
前两天知识小集群里有人讨论关于热修复的问题,对此我很是感兴趣,今天做为一个小集和你们探讨一下。虽然目前苹果严禁带有热修复功能的 APP 上线,一旦发现,将增长审核时间(大约是一周的时间)。苹果主要考虑到了安全问题,避免给本身找事,因此干脆禁用了 JSPatch。可是 JSPatch 使用的 API 并无违反苹果的规定,他也就没有一个十足的理由拒绝你的 APP 上线。这样就致使还有不少公司在悄悄地用 JSPatch。不过原理基本都是对 JSPatch 进行混淆后使用,固然若是你有能力本身实现一个 JSPatch 也能够。
被拒苹果的拒绝理由大概是这样的:
目前我了解到市面上主要经过如下几种方式进行混淆(若是对这个话题感兴趣,后续咱们会在【知识小集】公众号 进一步探讨):
目前使用官方提供的 JSPatch 服务任然能够过审,听说也是经过静态混淆-宏定义 这中方式。
Bugly 提供了热修复功能,它提供了一种对 JSPatch 混淆的方式。在 BuglyHotfixConfuse_pch.h
文件中把须要混淆的类名方法名替换掉。有兴趣的读者能够在这里 查看详细代码。
本身混淆固然是最保守的,苹果很难察觉。某天网上爆出一个 ZipArchive
安全漏洞,而这个漏洞的一个条件就是使用了相似 JSPatch 这种能够动态执行脚本的功能,而被爆出的 APP 经查确实使用混淆后 JSPatch,而他们采用的混淆方式也就是本身混淆。因此本身混淆 JSPatch 这条路是通的。本身混淆主要是理解 JSPatch 的原理,换一种方式来实现。
做者: 高老师很忙
Assets 想必你们都使用过,今天聊几个 Assets 比较方便的用法。
storyboard
或者 xib
布局的时候,设置颜色依旧要去设置具体的RGB值;而Assets给咱们提供了一个很方便的功能,能够建立 New Color Set
,就弥补了刚才方案的缺陷(以下图),而且代码中使用也很方便。-[UIImage resizableImageWithCapInsets:resizingMode:]
这个方法;而 Assets 为咱们提供了 Slicing 的功能(以下图),在 Assets 中直接设置后,在 storyboard 和 xib 中就能够直接显示拉伸后的图片,在代码中使用也及其方便,直接用 -[UIImage imageNamed:]
方法便可。Devices
设置,会让代码看着很清爽,不会存在判断机型再去设置图片的恶心代码。在设置横竖屏的时候也能够充分利用 Width Class
和 Height Class
两个参数(以下图)。我以为这 3 个用法在工做中仍是很实用的,固然 Assets 还有其余很好用的功能,欢迎你们一块儿交流。
做者: KANGZUBIN
当咱们要作 App 日志上报时,须要考虑到一种行为:App 在启动时就崩溃闪退了,并且当遇到连续启动闪退(也就是每次打开 App 必崩)时,那几乎是灾难,但更可怕是,若是没有有效的监测手段,咱们可能对已发生的这种线上严重问题绝不知情。
WeRead 团队博客的[《iOS 启动连续闪退保护方案》] (http://wereadteam.github.io/2016/05/23/GYBootingProtection/) 和 MrPeak 老师的《iOS App 连续闪退时如何上报 crash 日志》 分别介绍了两种简易的如何检测连续闪退的策略,在这里跟你们分享一下。
1)App 本地缓存维护一个计数变量,用于表示连续闪退的次数;
2)在启动入口方法 application:didFinishLaunchingWithOptions:
里判断 App 以前是否发生过连续闪退,若是有,则启动保护流程,自我修复,日志上报等,不然正常启动。判断的逻辑以下:
3)先取出缓存中的启动闪退计数 crashCount,而后把 crashCount 加 1 并保存;
4)接着使用 dispatch_after
方法在 5s 后清零计数,若是 App 活不过 5 秒计数就不会被清零,下次启动就能够读取到;
5)若是发现计数变量 > maxCount,代表 App 连续 maxCount 次连续闪退,启动保护流程,重置计数。
具体的代码以下图所示:
这种计数器方法逻辑简单,与原有的代码耦合小。但存在误报可能(用户在启动 App 后又当即 kill 掉,会被误认为是 crash),不过能够经过设置时间阈值或者在 applicationWillTerminate:
里标记 App 是被手动 kill 来减小误报。
咱们能够在本地保存一个 App 每次启动时间、闪退时间、手动关闭时间的时间数组,而后在 App 启动时根据分析各个时间戳判断是否存在连续闪退(当闪退时间减去启动时间小于阈值 5 秒时,则认为是启动闪退),具体以下:
1)App 每次启动时,记录当前时间 launchTs,写入时间数组;
2)App 每次启动时,经过 crash 采集库,获取上次 crash report 的时间戳 crashTs,写入时间数组;
3)App 在接收到 UIApplicationWillTerminateNotification
通知时,记录当前时间戳 terminateTs,写入时间数组。注意,之因此要记录 terminateTs,是为了排除一种特殊状况,即用户启动 App 以后当即手动 kill app。
若是咱们正确记录了上面三个时间戳,那么咱们能够获得一个与 App crash 行为相关的时间线,以下图:
根据各类时间线的行为特征,咱们只须要加上时间间隔判断,就能得知是否为连续两次闪退了。注意,若是两个 crashTs 之间若是存在 terminateTs,则不能被认为是连续闪退。
以上,介绍了两种检测 App 是否存在启动连续闪退的策略。
此外,对于连续闪退的保护方案以及连续闪退如何上报日志,请详细阅读开头提到的两篇博文。
知识小集是一个团队公众号,主要定位在移动开发领域,分享移动开发技术,包括 iOS、Android、小程序、移动前端、React Native、weex 等。每周都会有 原创 文章分享,咱们的文章都会在公众号首发。欢迎关注查看更多内容。
欢迎关注咱们的公众号:iOS-Tips,也欢迎加入咱们的群组讨论问题。能够公众号留言 ios、flutter、web、pwa、小程序 等关键词获取入群方式。