WWDC Quick Look 💓 By SwiftGGTeam
What's new in Foundation

What's new in Foundation

观看原视频

Highlight

Foundation 把 Locale 从引用类型改为值类型,并通过 #Predicate 宏把谓词查询的属性名与类型检查移到编译期。


核心内容

Foundation 这次更新的主线是把 ObjC 时代留下来的设计债一笔笔还掉。Locale 从引用类型变成值类型,听起来像是内部实现细节,但它直接干掉了一类多线程 bug:两个线程在用户切换系统语言的瞬间读到不同 locale 值,导致格式化结果不一致。这种 bug 极难复现,过去你只能靠加锁或者祈祷来规避。现在 Locale.current 返回的是调用时刻的快照,拿到手里就不会变。

JSONEncoderJSONDecoder 的底层重写带来了性能提升,对处理大量 API 响应的应用来说是白捡的优化。另一个实用变化是 OutputFormatting.withoutEscapingSlashes,终于可以控制 / 的转义行为了——某些后端对 \/ 的处理一直是个坑。

#Predicate 宏是这次的重头戏。NSPredicate 用字符串写 "age >= 18",拼错了只有运行时才知道;#Predicate 让 Swift 编译器在构建阶段就帮你检查类型和属性名。配合 SortDescriptor 的链式 API,Core Data 查询终于可以全链路类型安全了。


详细内容

#Predicate 把字符串查询变成 Swift 闭包,类型由编译器把关。下面这段是典型的用法:

struct Person {
    var name: String
    var age: Int
}

let adults = #Predicate<Person> { person in
    person.age >= 18
}

let sortByName = SortDescriptor(\Person.name)

关键点:

  • #Predicate<Person> 把谓词绑定到 Person 类型,闭包参数 person 的字段访问会被编译器检查。
  • person.age >= 18 直接是 Swift 表达式,写错属性名时 Xcode 立刻报错,免去运行时字符串解析的隐患。
  • SortDescriptor(\Person.name) 用 KeyPath 指定排序字段,避免老式字符串 key 拼写错误。
  • 这个谓词可以传给 SwiftData / Core Data 的 FetchDescriptor,端到端类型安全。

JSONEncoder 的输出控制可以用 outputFormatting 选项叠加:

let encoder = JSONEncoder()
encoder.outputFormatting = [.prettyPrinted, .withoutEscapingSlashes]

关键点:

  • .prettyPrinted 让输出带缩进,便于调试。
  • .withoutEscapingSlashes 关闭对 / 的转义,输出 http://example.com 而不是 http:\/\/example.com
  • 两个选项用 OptionSet 语法叠加,互不冲突。

核心启发

  • 做什么:把项目里所有 Locale.current 调用统一审计一遍。

    • 为什么值得做:多线程场景下 locale 漂移引起的格式化错乱极难复现,是潜在的线上问题。
    • 怎么开始:用 Xcode 的 Find Navigator 全局搜索 Locale.current,重点检查 GCD 队列与 async 上下文里的使用。
  • 做什么:把新代码里的 NSPredicate 字符串迁移到 #Predicate 宏。

    • 为什么值得做:编译期检查能拦住大部分拼写错误和类型不匹配,减少线上崩溃。
    • 怎么开始:从新增的查询逻辑入手,老代码改到相关模块时再顺手迁移。
  • 做什么:升级部署目标后跑一遍 JSON 解析的性能基线。

    • 为什么值得做:JSONEncoderJSONDecoder 的底层重写不需要改代码,是免费收益。
    • 怎么开始:用 XCTest 的 measure 块对大型 JSON payload 做基准测试,对比升级前后的耗时数据。

关联 Session

评论

GitHub Issues · utterances