iOS中的内嵌汇编

写一篇在iOS上使用汇编的文章的想法在脑袋里面停留了很久了,但是迟迟没有动手。虽然早前在做启动耗时优化的工作中,也做过通过拦截objc_msgSend并插入汇编指令来统计方法调用耗时的工作,但也只仅此而已。刚好最近的时间项目在做安全加固,需要写更多的汇编来提高安全性(文章内汇编使用指令集为ARM64),也就有了本文 内嵌汇编格式 __asm__ [关键词]( 指令 : [输出操作数列表] : [输入操作数列表] : [被污染的寄存器列表] ); 比如函数中存在a、b、c三个变量,要实现a = b + c这句代码,汇编代码如下: __asm__ volatile( "mov x0, %[b]\n" "mov x1, %[c]\n"...
Click to read more ...

Combine和SwiftUI

尽管今年的WWDC已经落幕,但在过去的一个多月时间,苹果给iOS开发者带来了许多惊喜,其中堪称最重量级的当属SwiftUI和Combine两大新框架 在更早之前,由于缺少系统层的声明式UI语言,在iOS系统上的UI开发对于开发者而言,并不友善,而从iOS13开始,开发者们终于可以摆脱落后的布局系统,拥抱更简洁高效的开发新时代。与SwiftUI配套发布的响应式编程框架Combine提供了更优美的开发方式,这也意味着Swift真正成为了iOS开发者们必须学习的语言。本文基于Swift5.1版本,介绍SwiftUI是如何通过结合Combine完成数据绑定 SwiftUI 首先来个例子,假如我们要实现上图的登陆界面,按照以往使用UIKit进行开发,那么我们需要: 创建一个UIT...
Click to read more ...

OOM与内存

微视的crash log会夹带应用剩余内存信息上报给服务器,希望借此协助诊断崩溃是否由OOM引发。多数情况下,OOM不直接导致crash,而是以SIGSEGV的信号错误,其操作逻辑更像是内存无法分配,却依然访问这个无效地址: int *ptr = malloc(sizeof(int *)); *ptr = 0x100; // crash by access invalid memory 下面是一个只保留了主线程调用栈的crash log(屏蔽部分敏感信息后): Handler: Signal Handler Hardware Model: iPhone8,2 Process: microvision [2581] Path: /var/containers/Bundle/...
Click to read more ...

记一次重构

技术重构 重构是软件开发过程中不断对软件代码进行打散重组,提高代码稳定性和可读性的处理手段之一。对【技术重构】进行关键信息提炼可以得到思维导图: 本文以微视最近一次音乐播放功能的重构为例回顾重构过程 重构步骤 业务梳理 微视4.8版本增加了音乐榜单功能,在更早之前的版本拥有音乐播放的界面只有音乐聚合页,相较于音乐聚合页同时只有一首歌曲需要控制播放,音乐榜单页存在切歌、榜单切换的场景,逻辑处置起来要棘手的多。另外由于音乐播放应该是一个通用能力,在重构前控制器需要维护AVPlayer的各种状态,代码格式如下: - (void)observeValueForKeyPath: (NSString *)keyPath ofObject: ...
Click to read more ...

质量监控-图片减包

经过多个版本迭代,项目在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 ...