iOS摸鱼周报 第四十三期

本文介绍了Apple开源的dyld4,探讨了dyld4相对于dyld3的改进,以及dyld4在iOS12上的libswift_Concurrency.dylib crash问题的解决方案。同时,文章详细解析了Synchronized的源码,解释了其内部的数据结构和加锁逻辑。此外,还推荐了优质博客和学习资料,包括Swift协议进阶、南大软件分析课程和iOS开发学习图谱。
摘要由CSDN通过智能技术生成

本期概要

  • 话题:dyld4 开源了。
  • Tips:Fix iOS12 libswift_Concurrency.dylib crash bug
  • 面试模块:Synchronized 源码解读
  • 优秀博客:Swift Protocol 进阶
  • 学习资料:南大软件分析课程,iOS 开发学习图谱
  • 开发工具:贝尔实验室开发的有向图/无向图自动布局应用,支持 dot 脚本绘制结构图,流程图等。

本期话题

@zhangferry:Apple 最近开源了 dyld4 的代码。通过阅读它的 Readme 文档,我们可以大致了解到 dyld4 相对 dyld3 做的改进有哪些。dyld3 出于对启动速度的优化,增加了启动闭包。应用首启和发生变化时将一些启动数据创建为闭包存到本地,下次启动将不再重新解析数据,而是直接读取闭包内容。这种方法的理想情况是应用程序和系统应很少发生变化,因为如果这两者经常变化,即意味着闭包可能面临失效。为了应对这类场景,dyld4 采用了 Prebuilt + JustInTime 的双解析模式,Prebuild 对应的就是 dyld3 中的启动闭包场景,JustInTime 大致对应 dyld2 中的实时解析,JustInTime 过程是可以利用 Prebuild 的缓存的,所以性能也还可控。应用首启、包体或系统版本更新、普通启动,dyld4 将根据缓存有效与否选择合适的模式进行解析。

dyld3 在不使用启动闭包的情况下会 fallback 到 dyld2,两套代码分别在两边,不利于行为的统一和维护,dyld4 做了逻辑统一(@鹅喵 补充)。所以 dyld4 的设计目标是更优的兼容性和逻辑统一。

还有一点,细心的开发者还在 dyld4 源码里发现了 realityOS 及 realityOS_Sim 相关的代码注释。很大可能苹果的 VR/AR 设备已经准备差不多了,静待今年的 WWDC 吧。

地址:apple-oss-distributions/dyld

开发Tips

整理编辑:Hello World

iOS12 libswift_Concurrency.dylib crash 问题修复

最近很多朋友都遇到了 iOS12 上 libswift_Concurrency 的 crash 问题,Xcode 13.2 release notes 中有提到是 Clang 编译器 bug,13.2.1 release notes 说明已经修复,但实际测试并没有。

crash 的具体原因是 Xcode 编译器在低版本 iOS12 上没有将 libswiftConcurrency.dylib 库剔除,反而是将该库嵌入到 ipa 的 Frameworks 路径下,导致动态链接时 libswiftConcurrency 被链接引发 crash。

问题分析

通过报错信息 Library not loaded: /usr/lib/swift/libswiftCore.dylib 分析是动态库没有加载,提示是 libswiftConcurrency.dylib 引用了该库。iOS12 本不该链接这个库,崩溃后通过 image list 查看加载的镜像文件会找到 libswiftConcurrency 的路径是 ipa/Frameworks 下的,查询资料了解到是 Xcode13.2 及其以上版本在做 Swift Concurrency 向前兼容时出现的 bug

问题定位

在按照 Xcode 13.2 release notes 提供的方案,将 libswiftCore 设置为 weak 并指定 rpath 后,crash 信息变更,此时 error 原因是 ___chkstk_darwin 符号找不到;根据 error Referenced from 发现还是 libswift_Concurrency 引用的,通过:

bash $ nm -u xxxAppPath/Frameworks/libswift_Concurrency.dylib 查看所有未定义符号(类型为 U), 其中确实包含了 ___chkstk_darwin,13.2 release notes 中提供的解决方案只是设置了系统库弱引用,没有解决库版本差异导致的符号解析问题。

error 提示期望该符号应该在 libSystem.B.dylib 中,但是通过找到 libSystem.B.dylib 并打印导出符号:

bash $ nm -gAUj libSystem.B.dylib 发现即使是高版本的动态库中也并没有该符号,那么如何知道该符号在哪个库呢?这里用了一个取巧的方式,run iOS13 以上真机,并设置 symbol 符号 ___chkstk_darwin, Xcode 会标记所有存在该符号的库,经过前面的思考,认为是在查找 libswiftCore 核心库时 crash 的可能性更大。

libSystem.B.dylib 路径在 ~/Library/Developer/Xcode/iOS DeviceSupport/xxversion/Symbols/usr/lib/ 目录下

如何校验呢,通过 Xcode 上 iOS12 && iOS13 两个不同版本的 libswiftCore.dylib 查看导出符号,可以发现,iOS12 上的 Core 库不存在,对比组 iOS13 上是存在的,所以基本可以断定 symbol not found 是这个原因造成的;当然你也可以把其他几个库也采用相同的方式验证。

通过在 ~/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值