惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
IT之家
IT之家
H
Heimdal Security Blog
Jina AI
Jina AI
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
爱范儿
爱范儿
T
Tailwind CSS Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
AWS News Blog
AWS News Blog
C
Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Hacker News
The Hacker News
The Cloudflare Blog
Hugging Face - Blog
Hugging Face - Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threatpost
S
Securelist
P
Privacy International News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 聂微东
博客园 - 叶小钗
J
Java Code Geeks
V
V2EX
博客园 - Franky
Spread Privacy
Spread Privacy
K
Kaspersky official blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Simon Willison's Weblog
Simon Willison's Weblog
Project Zero
Project Zero
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
C
Cybersecurity and Infrastructure Security Agency CISA
C
CERT Recently Published Vulnerability Notes
Latest news
Latest news
NISL@THU
NISL@THU
罗磊的独立博客
W
WeLiveSecurity
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园_首页
V
Visual Studio Blog

肘子的 Swift 记事本 | Fatbobman's Blog

当灵感跑在了结果前面 -- 肘子的 Swift 周报 #145 当每一次写入都有了新价格 -- 肘子的 Swift 周报 #144 当 Linux 成为“空气”:容器、Agent 与不再重要的“桌面之争” -- 肘子的 Swift 周报 #143 两个 SwiftUI 动画 Bug 排查小记 SPI 加入 Apple,Swift 迈向自举 -- 肘子的 Swift 周报 #142 Swift 还让你 Excited 吗? -- 肘子的 Swift 周报 #141 从 Size Class 到可用空间,horizontalSizeClass 还可靠吗? WWDC 26:AI 帮你看完了,然后呢? -- 肘子的 Swift 周报 #140 WWDC 2026 初印象:符合预期,但更务实 -- 肘子的 Swift 周报 #139 Core Data + Observation:从属性级响应到心智解放 稳定 > 新功能 -- 肘子的 Swift 周报 #138 用自定义 Layout 化解 SwiftUI List 的行高与间距跳变 从社区路标到生态基石:Dave Verwer 的新篇章 -- 肘子的 Swift 周报 #137 消失的 WWDC 愿望单 -- 肘子的 Swift 周报 #136 CocoaPods 正在退场,SwiftPM 才刚到第二章 -- 肘子的 Swift 周报 #135 让 AI 从称手到称心 -- 肘子的 Swift 周报 #134 Swift 并发正被更广泛地接纳 -- 肘子的 Swift 周报 #133 从 OpenSwiftUI 到 DanceUI:换个方式 Dive SwiftUI -- 肘子的 Swift 周报 #132 被 Vibe 摧毁的版权壁垒,与开发者的新护城河 -- 肘子的 Swift 周报 #131 苹果的罕见妥协:当高危漏洞遇上“拒升”潮 -- 肘子的 Swift 周报 #130 一墙之隔,不同的时空 -- 肘子的 Swift 周报 #129 我的 App 审核被卡了? -- 肘子的 Swift 周报 #128 CDE:一次让 Core Data 更像现代 Swift 的尝试 50 岁的苹果和 51 岁的我 -- 肘子的 Swift 周报 #127 Macbook Neo:苹果重回校园的起点 -- 肘子的 Swift 周报 #126 跨域传递 NSManagedObjectContext 为什么在 Swift 6.2 中不再报错?真正的变化不在编译器 Xcode 26.3 + Claude Agent:模型替换、MCP、Skill 与自适应配置 macOS 录屏软件开发实录:从像素抓取到元数据重现 isolated(any) 与 #isolation:让 Swift 闭包自动继承隔离域 在 tvOS 上活下來:一個非典型播放器的工程實錄 告别“可移植汇编”:我已让 Swift 在 MCU 上运行七年 独立开发者的试炼:Zipic 从 0 到 1 的产品化之路 逃离 Mac App Store:如何从零构建独立应用的分发与售卖体系 为什么父视图无法修改子视图的 @State Partytown 实战:修复 GTM 自定义事件与 dataLayer 失效问题 Swift 6 编译加速:启用 Swift-Syntax 预构建 (Prebuilts) Swift 模块化:使用 package 关键字实现 Target 间安全共享 Monorepo 实战:解决 VSCode/Cursor 中 SwiftLint 配置失效问题 VSCode/Cursor 测试 Core Data:手动编译 xcdatamodeld 指南
2026 年,为什么我仍在思考 Core Data
东坡肘子 · 2026-03-11 · via 肘子的 Swift 记事本 | Fatbobman's Blog

在 Apple 的持久化技术版图中,Core Data 早已不再是“最新”的那个名字。过去几年里,SwiftData 带来了更现代化的声明式体验;GRDB、SQLiteData 这类方案则让更多开发者重新思考关系型数据库在 Swift 项目中的位置。站在 2026 年回头看,Core Data 既不新,也不轻,甚至在很多代码层面的表现已经明显落后于今天的 Swift。

但这并不意味着它已经失去了价值:如果我们仍然选择 Core Data,那么能不能让它以一种更符合现代 Swift 的方式继续存在下去?

这篇文章不是要为 Core Data 辩护,也不是要说服新的开发者回到 Core Data。它更像是一篇问题整理:在 2026 年,为什么仍有人坚持使用 Core Data;而如果要继续使用它,我们今天真正需要解决的问题又是什么。

为什么到了 2026 年,仍然还有人使用 Core Data

Core Data 自诞生至今已经 21 年了。在这期间,苹果的开发生态经历了数轮演进:从 Objective-C 到 Swift,从 UIKit 到 SwiftUI,从 GCD 到现代并发模型。即便在 SwiftData 推出数年之后,仍有不少开发者在继续使用 Core Data,而且使用它的存量项目依然非常庞大。

继续坚持使用 Core Data 的开发者,大致出于以下几种考量:

  • 对 Core Data 足够熟悉,并不觉得它在今天已经“不可用”
  • 相比看上去更现代的 SwiftData,更看重 Core Data 某些成熟而关键的能力
  • 即便 GRDB / SQLiteData 提供了更强的性能或更直接的数据库控制力,仍然更喜欢 Core Data 的对象图设计思想和管理方式
  • 旧项目仍在使用 Core Data,迁移到其他框架的成本过高

如果只是从“还能不能用”的角度说,Core Data 当然还能用,而且在不少项目里依然是务实的选择。

但问题在于,它越来越不像今天 Swift 项目里的东西了

在现代 Swift / SwiftUI 工程中使用 Core Data,经常会有一种明显的错位感:它不是不能工作,而是它在代码层的表达方式、并发方式和工程协作方式,都越来越难与周围的现代代码风格自然地融合在一起。

所以,对仍在使用 Core Data 的人来说,真正的问题并不是“要不要立刻抛弃它”,而是:

如何让 Core Data 跟上项目其他部分已经发生的现代化演进。

Core Data 与现代 Swift 项目之间的错位

如果要寻找 Core Data 的进化方向,最好先明确它今天和现代 Swift 项目之间最主要的错位发生在哪里。

1. 模型代码的表现力已经落后于现代 Swift

和 SwiftData、SQLiteData 这类以代码为核心的声明方式不同,Core Data 的主流建模方式仍然是 Xcode 的模型编辑器。

但真正让 Core Data 与现代 Swift 项目脱节的,并不只是“模型放在编辑器里”这件事,而是它在 Swift 层面的模型代码表现力已经明显落后。

由于 Core Data 的底层历史来自 Objective-C,它在 Swift 世界中的默认模型声明方式始终带着很重的旧时代痕迹。很多在今天看起来理所当然的 Swift 语义,放到 NSManagedObject 上却并不能自然成立:

  • nil 不总是能清晰对应到底层数据模型的 null
  • Double / Float 这类值很难直接以符合直觉的 Optional 形式表达
  • 无法自然地把更丰富的 Swift 类型直接作为属性暴露出来
  • 想改善这些问题时,往往不得不依赖手工桥接、计算属性和额外样板代码

这些做法当然能解决局部问题,但代价是模型声明层会迅速变得嘈杂。开发者为了获得更自然的 Swift 表达,不得不写出大量与业务无关的桥接代码,而这些代码反过来又削弱了 Core Data 最宝贵的一部分体验:对象图本该带来的清晰感和直接感。

换句话说,今天 Core Data 的问题并不是“不能建模”,而是它在 Swift 层的建模代码已经越来越难以自然地表达你的意图。

2. 并发体验仍然停留在 GCD 时代

Core Data 中的 NSManagedObject 不是线程安全的。随着项目变大,把所有 CRUD 都放在主线程上显然不是长久之计。

尽管从 Xcode 26 开始,NSManagedObjectContext 已经被标注为 Sendable 了,但这并没有改变 Core Data 实际的并发使用方式。为了保证线程安全,开发者依然需要通过 perform 去包装绝大多数操作。

这和今天 Swift 世界主流的并发表达方式之间有很明显的时代错位。

和 SwiftData 提供的 @ModelActor 相比,Core Data 的并发代码通常有几个问题:

  • 很容易因为疏忽而写出线程不安全的代码
  • perform 嵌套闭包的写法不直观,心智负担很重
  • 很难形成统一、清晰、可复用的隔离边界
  • 这类负担还会进一步影响测试代码的质量,导致开发者更少去写系统性的并发测试

所以这里的问题也不是 Core Data “不能并发”,而是它的并发表达方式已经明显不适合今天的 Swift 开发习惯了。

3. 灵活性、类型安全与模型漂移之间的张力越来越大

Core Data 传统上在查询和排序上给了开发者很高的灵活性。

NSPredicateNSSortDescriptor 都支持基于字符串的声明方式。这样的 API 很古老,但它也确实提供了很强的自由度。问题在于,这种自由度始终是以运行时风险为代价的:一旦字符串写错,就会造成运行时错误。

这也是 SwiftData、SQLiteData 这类新方案纷纷转向类型安全声明方式的主要原因。

但事情并没有那么简单。

类型安全当然能更早发现问题,但它往往也会压缩灵活调整的空间。对于很多已经上线、已经接入同步、或者底层模型已经不适合轻易变动的项目来说,属性名称、持久化字段名称、查询代码之间往往已经形成了很脆弱的平衡。一旦业务语言发生变化,开发者未必真的有空间去调整底层模型。

在这种情况下,开发者往往会选择在 Swift 层做一层映射,而不直接改动底层模型:

var title: String {
    get {
        guard let value = value(forKey: "name") as? String else {
            preconditionFailure("Missing required value for `title` (name).")
        }
        return value
    }
    set {
        setValue(newValue, forKey: "name")
    }
}

这确实能让表现层的命名更贴近当前业务,但新的问题也随之出现了:

  • Swift 属性名和持久化字段名脱节
  • 基于字符串编写的谓词和排序代码更容易出错
  • 手工映射层越来越厚,代码与底层模型发生漂移的概率越来越高

于是你会发现,问题已经不只是“字符串 API 不够安全”,而是:

一旦项目进入长期演进阶段,灵活性、类型安全和模型一致性之间会形成持续的张力。

真正棘手的,不只是 API 老,而是它越来越依赖经验与自觉

对于上面这些问题,我过去写过不少文章,也分享过不少在现代项目中继续使用 Core Data 的经验做法。但回头看,这些经验型解决方案有一个共同前提:开发者必须真正理解 Core Data 的底层行为,并且愿意持续遵守一套隐性的规范。

对于经验丰富的人类开发者来说,这件事或许还能做到。但在今天,这种前提已经越来越不牢靠了。

一方面,项目规模越来越大,团队协作越来越复杂,代码规范如果只是“约定俗成”,最终往往会逐渐失效。另一方面,AI 辅助编程正在快速进入日常开发流程,而大模型天然会优先输出它在预训练阶段见过的“常见写法”,而不是你项目内部那套需要长期维护的、细微但关键的规范。

这意味着,仅靠经验文章、团队自觉,甚至仅靠 Skill 去约束 AI 代码生成,已经很难真正解决问题了。

如果一套使用方式真的适合现代项目,它就不应该只是“资深开发者脑中的经验”,而应该尽可能体现在:

  • 更清晰的 API 设计里
  • 更稳定的源码表达层里
  • 更可验证的工具链里
  • 更容易被人和 AI 同时遵守的工作流里

换句话说,Core Data 今天真正缺的,也许不是更多技巧,而是一套能把这些技巧固化下来的表达方式和工程化支撑。

如果不打算替换 Core Data,我们还能做什么

到了这里,问题已经比较明确了。

如果你已经决定离开 Core Data,这篇文章对你意义不大——你完全可以转向 SwiftData、SQLiteData 或其他更符合当前偏好的方案。

但如果你仍然认可 Core Data 的对象图建模方式,仍然需要它成熟的迁移能力和历史兼容性,那么问题就不再是”要不要离开”,而是:有没有可能在不放弃 Core Data 的前提下,让它在现代 Swift 项目里重新站稳脚跟。

我过去一段时间一直在思考这个问题,最终把它落实进了一个开源库:CoreDataEvolution

它不是一个取代 Core Data 的新框架,也不是要把开发者重新拉回旧技术。它做的事情更像是补缺:

  • 用 Swift Macros 重塑模型声明层,让 NSManagedObject 的表达更接近今天的 Swift 语义
  • 引入 SwiftData 风格的 actor 隔离,让并发代码有清晰可验证的边界
  • 提供映射层,在不轻易改动底层模型的前提下,同时改善排序、谓词等代码中的类型安全与命名表达
  • 提供命令行工具,在源码声明和 Core Data 模型之间建立可持续的自动对齐机制

这些不是技巧的集合,而是一套试图把”经验”固化成工程结构的尝试。

下一篇文章里,我会展开聊具体的设计思路和实现方式。