# 老司机 iOS 周报 #283 | 2024-04-01

![ios-weekly](https://github.com/SwiftOldDriver/iOS-Weekly/blob/master/assets/weekly-header/283.jpg?raw=true)
老司机 iOS 周报，只为你呈现有价值的信息。

你也可以为这个项目出一份力，如果发现有价值的信息、文章、工具等可以到 [Issues](https://github.com/SwiftOldDriver/iOS-Weekly/issues) 里提给我们，我们会尽快处理。记得写上推荐的理由哦。有建议和意见也欢迎到 [Issues](https://github.com/SwiftOldDriver/iOS-Weekly/issues) 提出。

**周报编辑组又来新人啦~** 

欢迎 [DylanYang](https://github.com/Dylan19Yang) 加入老司机技术，目前就职于字节跳动，参与音乐相关客户端开发，业余喜欢看看番、打打游戏。

欢迎 [Kyle-Ye](https://github.com/Kyle-Ye) 加入老司机技术，他是 Swift Documentation Workgroup 成员，独立开发者，专注于 OpenSwiftUI / Swift 相关研究。

**希望 DylanYang 与 Kyle-Ye 的加入也能为大家带来更多元化的内容输出！**

## 文章

### 🐎 [A better pull request](https://blog.developer.atlassian.com/a-better-pull-request/)

[@Smallfly](https://github.com/iostalks)：在使用 Git 时，执行 `git diff master...alice/master`，「三个点」查看当前分支与远端分支的差异，清楚的了解将要拉取的内容，然而当远端分支有提交时，新的提交无法在 diff 中显示，这么设计有其合理性。本文作者认为不太方便，在 Bitbucket 中使用「两个点」展示与最新分支的 diff 会更清晰。对实现感兴趣的同学可阅读原文了解。

### 🐎 [SwiftUI Previews-based architecture](https://blog.thomasdurand.fr/story/2024-03-15-preview-based-architecture/)

[@DylanYang](https://github.com/Dylan19Yang)：本文作者通过一个简单的 demo 阐述了如何实现基于 SwiftUI Previews 框架的开发流程。同时作者也借此引入了他认为实现代码灵活性和解耦的两个工具：接口（Interface）和依赖注入（Dependency Injection），并在 demo 中进行了实践。接口在 Swift 中以原生的 Protocol 呈现而依赖注入则可以凭借 SwiftUI 中的环境变量（Environment Values）来实现。此外借助 `@Observable`、`ObservableObject` 和环境变量等能力，整个框架在渲染性能、内存和数据同步方面都非常优秀。

### 🐕 [Using a Swift macro to generate an EnvironmentKey](https://www.swiftwithvincent.com/blog/using-a-swift-macro-to-generate-an-environmentkey)

[@Barney](https://github.com/BarneyZhaoooo)：这篇文章介绍了如何使用名为 `@EnvironmentStorage` 的 Swift 宏来简化 SwiftUI 中 Environment 的使用，自动生成 EnvironmentKey 和相关的 EnvironmentValues 代码，减少样板代码，提高开发效率。通过引入 SwiftUIMacros 包并应用该宏，开发者只需定义属性名、类型和默认值即可快速创建环境存储，从而节省时间并减少错误。

### 🐕 [Be Careful When You Initialize a State Object](https://jaredsinclair.com/2024/03/14/state-object-autoclosure.html)

[@AidenRao](https://weibo.com/AidenRao)：在这篇文章中，Jared Sinclair 谈到了在使用 @StateObject 时需要注意的一些最佳实践：如果你必须显式地初始化 @StateObject，请密切注意属性包装器的初始化参数是一个名为 thunk 的转义闭包，而不是一个名为 wrappedValue 的对象。请在闭包内部完成所有封装对象的初始化和预处理，否则就会损害性能优势，而性能优势很可能正是你使用 @StateObject 的初衷。

### 🐕 [Unrestricted View Replication](https://bryce.co/replicating-views/)

[@JonyFang](https://github.com/JonyFang): 本文讨论了在 iOS 应用中单 UIView 实例多副本场景的处理。首先介绍了使用私有 API `_UIPortalView` 来实现复制视图的方法，但指出这不符合苹果的规定，因此需要寻找其他解决方案。

接下来，引出 `CAReplicatorLayer` 来实现复制视图的方法。`CAReplicatorLayer` 可以创建多个视图的副本，并对每个副本应用递归变换。文中也讨论了使用嵌套的 `CAReplicatorLayer` 来创建复杂布局的方法，但指出这种方法会导致视图复制的复杂性和性能问题。
最后，提到了 `CAReplicatorLayer` 的 `instanceDelay` 属性，该属性可以在复制的视图实例之间创建动画延迟。

### 🐎 [How to run asynchronous code in Swift Playground correctly?](https://antran.app/2024/swift_playground_async_execution/)

[@zoeGuo](https://github.com/zoeGuo)：Swift Playground 是快速试验 Swift 代码的绝佳工具。默认情况下，Swift Playground 从程序的顶部到底部同步执行代码。当运行异步代码时，会遇到代码执行不会结束的问题。引入 `PlaygroundSupport` 库，配合使用 `needsIndefiniteExecution`、`finishExecution()` 两个 API，即可在 Swift Playground 中编写异步代码并顺利执行，文中例举了在 Swift Playground 中使用 dispatchGroup 完成异步逻辑的操作。

### 🐎 [Make Your iOS App Smaller with Dynamic Frameworks](https://www.emergetools.com/blog/posts/make-your-ios-app-smaller-with-dynamic-frameworks)

[@Leo](https://github.com/LeoMobileDeveloper)：iOS 的 Widget 和 ShareExtension 是独立的 target，sandbox 和主 App 是独立的，如果多个独立的 Target 采用静态链接的方式来构建，那么某些基础库的的代码和资源会被在多个 Target 之间拷贝多份。本文提出了一种解决多 Target 之间共享代码和资源的方式，即用 Dynamic Framework，可以显著优化包大小。

## 内推

重新开始更新「iOS 靠谱内推专题」，整理了最近明确在招人的岗位，供大家参考

具体信息请移步：https://www.yuque.com/iosalliance/article/bhutav 进行查看（如有招聘需求请联系 iTDriverr）

## 关注我们

我们是「老司机技术周报」，一个持续追求精品 iOS 内容的技术公众号，欢迎关注。

**关注有礼，关注【老司机技术周报】，回复「2023」，领取 2023 及往年内参**

![](https://github.com/SwiftOldDriver/iOS-Weekly/blob/master/assets/qrcode_for_wechat.jpg?raw=true)

同时也支持了 RSS 订阅：https://github.com/SwiftOldDriver/iOS-Weekly/releases.atom 。

## 说明

🚧 表示需某工具，🌟 表示编辑推荐

预计阅读时间：🐎 很快就能读完（1 - 10 mins）；🐕 中等 （10 - 20 mins）；🐢 慢（20+ mins）
