You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复@Sendable闭包中捕获非Sendable类型ISO8601DateFormatter的警告?

修复ISO8601DateFormatter在@Sendable闭包中的捕获警告

问题代码

let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions.insert(.withFractionalSeconds)
decoder.dateDecodingStrategy = .custom({ decoder in
    let container = try decoder.singleValueContainer()
    let dateStr = try container.decode(String.self)
    return dateFormatter.date(from: dateStr) ?? Date()   //warning
})

出现警告:Capture of 'dateFormatter' with non-sendable type 'ISO8601DateFormatter' in a @Sendable closure

修复方案

方案一:将dateFormatter标记为Sendable(iOS16+/macOS13+适用)

从iOS16和macOS13开始,ISO8601DateFormatter原生符合Sendable协议,直接声明类型即可消除警告:

let dateFormatter: ISO8601DateFormatter & Sendable = ISO8601DateFormatter()
dateFormatter.formatOptions.insert(.withFractionalSeconds)
decoder.dateDecodingStrategy = .custom({ decoder in
    let container = try decoder.singleValueContainer()
    let dateStr = try container.decode(String.self)
    return dateFormatter.date(from: dateStr) ?? Date()
})

如果是低版本系统,可使用@unchecked Sendable手动标记(苹果文档明确ISO8601DateFormatter是线程安全的,可安全使用):

let dateFormatter = ISO8601DateFormatter() as @unchecked Sendable
dateFormatter.formatOptions.insert(.withFractionalSeconds)
decoder.dateDecodingStrategy = .custom({ @Sendable [dateFormatter] decoder in
    let container = try decoder.singleValueContainer()
    let dateStr = try container.decode(String.self)
    return dateFormatter.date(from: dateStr) ?? Date()
})

方案二:在闭包内部创建dateFormatter

直接在闭包内初始化ISO8601DateFormatter,避免外部变量捕获:

decoder.dateDecodingStrategy = .custom({ decoder in
    let dateFormatter = ISO8601DateFormatter()
    dateFormatter.formatOptions.insert(.withFractionalSeconds)
    let container = try decoder.singleValueContainer()
    let dateStr = try container.decode(String.self)
    return dateFormatter.date(from: dateStr) ?? Date()
})

注意:此方法每次调用闭包都会创建新的格式化器,频繁解码时可能存在性能损耗。

方案三:使用静态常量复用格式化器(推荐)

利用静态常量的懒加载和线程安全特性,既复用格式化器,又避免捕获问题:

// 在类/结构体内部定义静态格式化器
private static let dateFormatter: ISO8601DateFormatter = {
    let formatter = ISO8601DateFormatter()
    formatter.formatOptions.insert(.withFractionalSeconds)
    return formatter
}()

// 解码时使用静态格式化器
decoder.dateDecodingStrategy = .custom({ decoder in
    let container = try decoder.singleValueContainer()
    let dateStr = try container.decode(String.self)
    return Self.dateFormatter.date(from: dateStr) ?? Date()
})

内容的提问来源于stack exchange,提问作者erotsppa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 01:12:16