Swift最佳实践Skill swift-best-practices

这是一个用于在iOS或macOS项目中编写或审查Swift代码的技能,应用现代Swift 6+最佳实践、并发模式、API设计指南和迁移策略。关键词:Swift,iOS,macOS,并发,async/await,actor,MainActor,Sendable,移动开发,最佳实践,代码质量。

移动开发 0 次安装 2 次浏览 更新于 3/20/2026

名称: swift-best-practices 描述: 该技能应在为iOS或macOS项目编写或审查Swift代码时使用。应用现代Swift 6+最佳实践、并发模式、API设计指南和迁移策略。涵盖async/await、actors、MainActor、Sendable、类型化throws和Swift 6破坏性变更。

Swift最佳实践技能

概述

应用现代Swift开发最佳实践,专注于Swift 6+特性、并发安全性、API设计原则以及针对macOS 15.7+的iOS和macOS项目的代码质量指南。

何时使用此技能

在以下情况使用此技能:

  • 为iOS或macOS应用程序编写新的Swift代码
  • 审查Swift代码的正确性、安全性和风格
  • 实现Swift并发特性(async/await、actors、MainActor)
  • 设计Swift API和公共接口
  • 将代码从Swift 5迁移到Swift 6
  • 解决并发警告、数据竞争问题或与Sendable/隔离相关的编译器错误
  • 使用Swift 6和6.2中引入的现代Swift语言特性

核心指南

基本原则

  1. 使用时的清晰度至关重要 - 通过检查使用案例来评估设计,而不仅仅是声明
  2. 清晰胜于简洁 - 紧凑代码来自类型系统,而非最少字符
  3. 为每个公共声明编写文档 - 如果无法简单描述功能,API可能设计不佳
  4. 按角色命名,而非类型 - var greeting = "Hello" 而不是 var string = "Hello"
  5. 偏爱通过简单实现的优雅 - 避免过度工程,除非复杂性确实需要

Swift 6并发模型

Swift 6默认启用完整的并发检查,基于区域的隔离(SE-0414)。编译器现在证明代码安全性,消除许多误报,同时在编译时捕获真正的并发问题。

关键理解:

  • Async ≠ 后台 - async函数可以暂停,但不自动在后台线程运行
  • Actors通过自动同步保护可变共享状态
  • @MainActor 确保UI相关代码在主线程执行
  • 全局actor隔离类型自动为 Sendable

基本模式

Async/Await

// 使用async let进行并行执行
func fetchData() async -> (String, Int) {
    async let stringData = fetchString()
    async let intData = fetchInt()
    return await (stringData, intData)
}

// 在长时间运行的操作中始终检查取消
func process(_ items: [Item]) async throws -> [Result] {
    var results: [Result] = []
    for item in items {
        try Task.checkCancellation()
        results.append(await process(item))
    }
    return results
}

MainActor用于UI代码

// 在类型级别应用以实现一致的隔离
@MainActor
class ContentViewModel: ObservableObject {
    @Published var images: [UIImage] = []

    func fetchData() async throws {
        self.images = try await fetchImages()
    }
}

// 当直接await可行时,避免使用MainActor.run
await doMainActorStuff()  // 好
await MainActor.run { doMainActorStuff() }  // 不必要

Actor隔离

actor DataCache {
    private var cache: [String: Data] = [:]

    func store(_ data: Data, forKey key: String) {
        cache[key] = data  // 在actor内部无需await
    }

    nonisolated func cacheType() -> String {
        return "DataCache"  // 无需await - 不访问隔离状态
    }
}

常见陷阱避免

  1. 不要不必要地将函数标记为 async - async调用约定有开销
  2. 永远不要将 DispatchSemaphore 与async/await一起使用 - 死锁风险
  3. 不要创建无状态的actors - 使用非隔离async函数代替
  4. 避免分割隔离 - 不要在一个类型内混合隔离域
  5. 检查任务取消 - 长时间操作必须检查 Task.checkCancellation()
  6. 不要假设async意味着后台 - 如果需要,明确将工作移到后台
  7. 避免过多的上下文切换 - 在同一隔离域内分组操作

API设计快速参考

命名约定

  • 类型/协议:UpperCamelCase
  • 其他:lowerCamelCase
  • 描述能力的协议:-able-ible-ing后缀(EquatableProgressReporting
  • 工厂方法:以 make 开头(x.makeIterator()
  • 可变对:命令式vs过去分词(x.sort() / x.sorted()

按副作用命名方法

  • 无副作用:名词短语(x.distance(to: y)
  • 有副作用:命令式动词(x.append(y)x.sort()

参数标签

  • 当参数无法区分时省略:min(number1, number2)
  • 值保持转换省略第一个标签:Int64(someUInt32)
  • 介词短语在介词处标签:x.removeBoxes(havingLength: 12)
  • 标签所有其他参数

Swift 6破坏性变更

必须显式用@MainActor标记类型(SE-0401)

属性包装器不再自动推断actor隔离。

@MainActor
struct LogInView: View {
    @StateObject private var model = ViewModel()
}

全局变量必须是并发安全的(SE-0412)

static let config = Config()  // 常量 - 好
@MainActor static var state = State()  // Actor隔离 - 好
nonisolated(unsafe) var cache = [String: Data]()  // 不安全 - 谨慎使用

其他变更

  • @UIApplicationMain/@NSApplicationMain 已弃用(使用 @main
  • 存在类型必须使用 any
  • 导入可见性需要显式访问控制

API可用性模式

// 基本可用性
@available(macOS 15, iOS 18, *)
func modernAPI() { }

// 带有消息的弃用
@available(*, deprecated, message: "使用newMethod()代替")
func oldMethod() { }

// 带有自动修复的重命名
@available(*, unavailable, renamed: "newMethod")
func oldMethod() { }

// 运行时检查
if #available(iOS 18, *) {
    // iOS 18+代码
}

// 反向检查(Swift 5.6+)
if #unavailable(iOS 18, *) {
    // iOS 17及以下
}

关键差异:

  • deprecated - 警告,允许使用
  • obsoleted - 从特定版本起错误
  • unavailable - 错误,完全阻止使用

如何使用此技能

编写代码时

  1. 应用命名约定,遵循基于角色、清晰优先的原则
  2. 使用适当的隔离(UI用@MainActor,可变状态用actors)
  3. 正确实现async/await模式,并处理适当的取消
  4. 遵循Swift 6并发模型 - 信任编译器的流分析
  5. 用清晰、简洁的摘要记录公共API

审查代码时

  1. 检查并发安全违规
  2. 验证适当的actor隔离和Sendable一致性
  3. 确保async函数正确处理取消
  4. 验证API命名遵循Swift指南
  5. 确认可用性注释对目标平台正确

代码质量标准

  • 最小化注释 - 代码应尽可能自文档化
  • 避免过度工程和不必要的抽象
  • 使用基于角色的有意义的变量名,而非类型
  • 遵循已建立的项目架构和模式
  • 优先使用 count(where:) 而非 filter().count
  • 对固定大小、性能关键的数据使用 InlineArray
  • 信任编译器的并发流分析 - 避免不必要的 Sendable 一致性

资源

参考/

当需要深入信息时加载的详细参考材料:

  • api-design.md - 完整的API设计约定、文档标准、参数指南和命名模式
  • concurrency.md - 详细的async/await模式、actor最佳实践、常见陷阱、性能考虑和线程安全模式
  • swift6-features.md - Swift 6/6.2中的新语言特性、破坏性变更、迁移策略和现代模式
  • availability-patterns.md - 全面的@available属性使用、弃用策略和平台版本管理

当需要超出上述核心指南的详细信息时,加载这些参考。

平台要求

  • Swift 6.0+编译器用于Swift 6特性
  • Swift 6.2+用于InlineArray和增强的并发特性
  • macOS 15.7+与适当的SDK
  • iOS 18+用于最新的平台特性
  • 使用 #available 进行运行时平台检测
  • 使用 @available 进行API可用性标记