廖林

廖林

Observation

Observation|创建 ViewModel 实例的方式

Combine 在 Combine 框架中,通常使用 @StateObject 在 View 中创建 ViewModel 实例。 ViewModel 实例的生命周期: * @State 跟随 View * @StateObject 独立管理,View 重建时保持 以上,是很好的实践方案。 Observation 中的问题 但在 Observation 框架中,不再能使用 @StateObject。如果使用 @State,会导致 ViewModel 预期之外的创建。 实际情况很复杂,并不是每次 View 更新都会导致 ViewModel 重建。例如如果有多个 View 使用同一个 ViewModel(例如 SummaryView 和 DetailView),就会导致同时存在多个 ViewModel
2 min read
Observation

Observation|使用 withObservationTracking 监听跨对象依赖变化

使用 Observable 标记的类,可以让 SwiftUI 的视图自动响应数据变化并刷新界面。但如果数据变化发生在视图之外,我们该如何观察这些变化呢? 一种常见的场景是跨 ViewModel 的属性依赖:在一个 ViewModel 中,可能需要根据另一个 ViewModel 的属性变化来更新自身的数据——例如调用 fetch() 方法重新获取内容。那么,如何才能在源数据变化时,确保依赖方能感知并作出响应? 我们在以下文章中,探讨了如何在 Observable 类中使用 didSet 属性观察器来监听数据变化: Observation|使用 didSet/willSet 属性观察器了解如何使用 Swift 中的属性观察器。Code With Ivens廖林 虽然 didSet 对监听自身属性变化非常有用,但它无法处理跨 ViewModel 的依赖关系。这时,withObservationTracking 就派上用场了 —— 它专为监听其他 Observable
2 min read
StoreKit

StoreKit|为 App 功能添加会员限制

条件渲染 通过用户当前权限,条件渲染不同的 View 视图: 但这种方式的缺陷在于,对于不同的功能,需要自定义实现不同的“PremiumFeatureRow”组件。 并且,在 PremiumFeatureRow 组件中,需要实现点击打开订阅页面的逻辑。 通用修饰器 创建一个通用的 PremiumFeatureModifier 修饰器, * 对于非会员用户,设置 .disabled(true),并显示会员徽章。 * 封装导航到订阅页面的逻辑。 在需要的地方,直接使用 .premiumFeature() 修饰器,无需格外的代码: 这种方式的缺陷是: * 仅对支持.disabled(true)的组件有用,例如 Button。 * 对于 Picker 组件,理想情况下,对于非会员用户,我们仍然希望展示可选项,但不可点击。但这种方式会导致 Picker 整个不可点击。
1 min read
LLM

V0|快速开发 Web 应用原型

V0 vs Cursor vs CC 每个工具我都经过深度使用,对于创建简单的 Landing Page 网页应用,优先使用 V0。 * V0 和 Vercel 绑定,V0 可以直接调用 Vercel 的数据库。 * V0 支持 Supabase、Grok 等集成。 * V0 预设了一套经过筛选、优化的技术栈(Next.js + shadcn/ui + Tailwind CSS),并且对最新文档有充分的了解。 * V0 原型设计的速度远快于 Cursor 和 CC,通常在几分钟内即可完成。 第二点特别重要,现在 Web 开发技术已经太过成熟,有过多的框架、组件库、动画库等供选择,而 Claude
3 min read
Claude Code|使用 CLAUDE.md 添加规则
LLM

Claude Code|使用 CLAUDE.md 添加规则

CLAUDE.md 是一个特殊文件,Claude 在开始对话时会自动将其纳入上下文。类似于 Cursor 中的 Rules。 CLAUDE.md 文件没有固定格式要求,应当保持内容简洁且易于阅读。 # Bash 命令 - npm run build:构建项目 - npm run typecheck:运行类型检查器 # 代码风格 - 使用 ES 模块(import/export)语法,避免使用 CommonJS(require) - 尽可能使用解构导入(例如:import { foo } from 'bar') # 工作流程 - 完成一系列代码更改后务必运行类型检查 - 为了性能,
3 min read
MVVM 架构|协调 Service 层与Manager 层
架构(Architecture)

MVVM 架构|协调 Service 层与Manager 层

在使用 MVVM 架构的 Swift 项目,可以抽象出 MVVM 核心层和支持层。 * 核心层包含基本的 Model、View 和 ViewModel。 * 支持层包含 Service、Manager 和其他工具类(Utilities)。 一个完整的项目结构是这样: 在涉及 SwiftData 的功能模块,会更复杂一些。 Manager 和 Service 的协调关系 Service > Manager 典型的调用链路: View → ViewModel → Service → Manager → 外部资源 Service 层级高于 Manager,在 Service 调用多个 Manager。 在 ViewModel 中调用 Service * 避免在 View 中直接调用
5 min read
Concurrency|Swift 6.2 让并发更容易控制
Swift-Concurrency

Concurrency|Swift 6.2 让并发更容易控制

Swift Concurrency 实际上包含异步和并发两个部分,他们是不同的概念: * 异步:async/await 语法,让代码不阻塞当前线程,后续代码可以继续执行。 * 并发:使用 Task 与 Actor 等并发原语,控制任务在哪个线程执行。 以下是关于 Swift Concurrency 的几个核心: 1 - 使用异步,并不意味着一定在后台线程执行 实际上,在大部分情况下,任务仍然在调用它的线程中执行 —— 这避免了数据竞争的问题,但仍然可能运行卡顿。 对于耗时但轻量级的任务,使用异步能很好的解决卡顿问题,最常见的场景是处理网络请求。然而,对于一些非常消耗性能的繁重任务,如果在主线程执行,即使使用异步语法,也会导致运行卡顿 —— 因为主线程资源可能被耗尽。 2 - 可以使用 Task 控制任务执行的线程 理想情况下,对于繁重的任务,应当将它从主线程剥离分派到后台线程执行,从而保证 App 界面运行流程
3 min read