遊戲/程序/更新/二次開發/小作品相關發佈
Dec 27
背景

我们知道iOS项目产物中是可以加入开发者的动态库(framework)的,如我们工程中使用的UnityFramework.framework。
正常情况下,在工程中link的动态库是程序启动时就会加载的(通过macho的LC_LOAD_DYLIB指令),会加载起包括用户加入的动态库和所有系统库。不过如果我们将framework构建完成并签名,不参与link而是直接放入资源中,这个动态库就会像资源一样正常的放在那里,程序中则可以通过dlopen或者CFBundleLoadExecutable将动态库手动加载起来,实现部分代码的用时加载,即iOS的动态库懒加载
點擊在新視窗中瀏覽此圖片
Mar 23
大量使用lottie的iOS应用会注意到,线上会存在大量的imageWithContentsOfFile卡顿。lottie使用imageWithContentsOfFile的地方很显然,即LOTLayerContainer的_setImageForAsset方法。这个方法在做啥?即如果当前layer是位图layer,从磁盘或者别的地方加载位图。而这里的卡顿,很显然:

1. 每个lottie从文件加载时,都会在此处从磁盘imageWithContentsOfFile加载图片,在主线程IO卡顿和图片解码产生卡顿风险。
2. 因为lottieView每次创建都是从文件创建的,即lottie资源本身没有实例机制,因此每一个重复的lottie创建都会重复imageWithContentsOfFile过程,加剧卡顿。
Feb 1
在上次讨论iDOT多线程png时,搜索到另一个领域的文章:iOS减包实战Compress PNG Files作用分析。其中提到了XCode构建过程中pngcrush的压缩过程会对png文件逆优化,就包括将png更新为iDOT格式(上文还不清楚iDOT的含义)。该文章建议的修复方案是修改资源属性,让构建过程对png不做处理,但是显然pngcrush对png渲染肯定有正向收益的,本文的目的即分析pngcrush的逆优化的实际缺陷与修复方案。(结合上文阅读)
Jan 31
最近有老外建立了一个新的项目,Block Protocol(https://blockprotocol.org),暂时简称“块协议”,目前还处于非常前期的阶段。它提出了一种思路与面向Web GUI的方案,通过块协议标准化的GUI块搭建应用与数据驱动逻辑,来构成人类与机器均友好的GUI应用。

听起来和一般我们所说的组件式或者模块式开发并没有什么不同,但是从块协议本身的视角,协议比实现更有价值,因此小议下blockprotocol的零零碎碎。
Jan 4
最近网络上有这么一个帖子:https://www.da.vidbuchanan.co.uk/widgets/pngdiff/。其中展示了一张图片,下半部分在苹果的系统与其他系统上展示不一致,其中的讨论使用苹果系统(包括iOS/OS X)设计的一种私有png chunk即iDOT,在mac上通过系统截屏截取的png就可以看到这个chunk。

目前网络上能搜到关于iDOT的描述,都是以截图的这种png为基准,分析出png分为两段的情况下,双线程解析png是iDOT是如何描述的(https://www.hackerfactor.com/blog/index.php?/archives/895-Connecting-the-iDOTs.html),不过其中还包含大量不准确(unknown)的字段,并且也不清晰如何描述分为两段以上即开启更多线程解析的方式。因此本次笔者经过逆向分析,得到了准确的多线程iDOT数据结构与全部字段含义,与一部分苹果的png decoder的iDOT校验逻辑,希望对后续该格式利用有所帮助。
Dec 21
在讨论js容器桥注入方案时,不可避免的会聊到react-native所搭建的JavascriptInterface(这是RN自己造的词,不过本文用JSI指代相同类型的方案)。JSI类方案一般确实不会有人提,核心原因是——除了RN,几乎没有什么方案是直接使用JSCore进行js执行的,而是通过Webview进行的h5页面执行,而对于webview来说,是无法直接拿到jscore的(严格来说只有iOS的UIWebview能拿到jscore,但是已经被淘汰了),
Dec 13
上次讨论Webview同步桥落地方案(https://lrdcq.com/me/read.php/151.htm)时,核心寻找了在js中表现为同步,但是实际为异步的方案,其中同步xhr这个特性(https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests)虽然在部分浏览器中会显示deprecated,但是并没有被ban掉,因此完全可以使用该特性在普通web中完成阻塞式API调用。这里尝试用该方案封装一个sleep函数,既不是for循环算时间这样消耗算力的sleep,也不是await这样的假同步sleep了。
Dec 12
在做Web容器方式时,业界目前一般采用的方案都是WebViewJavaScriptBridge拓展于Android/iOS上的实现。原理是基于iframe url request或者webkit.messageHandlers/Android JavascriptInterface进行js->native通信,evalJavascript的native->js通信,并相互维护call queue来保持对外一致。显然这个实现方案暴露的Bridge API必须是异步的,可以抽象为
callAPI(apiName: string, param: array, callback: function(result: any): void): void;

但是实际开发过程中异步bridge还是有不便之处,如storage / environmentinfo这类的桥,同步桥还是更方便易用。
Nov 20
一般我们说web页面解析特别是其中的js执行是“单线程”的,并且这是js这门语言的特点。本身确实没什么,但是实际项目实践中,特别是目前重js的spa大行其道的今天,界面中绝大部分的运行时卡顿,如滚动掉帧,事件响应延迟,均是js卡顿引起的。比较常见的卡顿常见如大量json序列化反序列化,对象deepcopy,界面diff刷新不收敛,总之代码稍微写得烂了一点页面性能就不堪入目,更别说编写大型项目如动画/3d内项目时大量货真价实的运输拖慢帧率了。