fix(concurrency): clear 4 Swift 6 warnings under default MainActor isolation

- ModelStore/FileVault: drop nonisolated(unsafe) on shared, mark all instance
  methods nonisolated (they only read filesystem); ModelKind enum also nonisolated
- AIRuntime ↔ ModelStore cross-actor call resolved by the above
- LLMSession: replace deprecated Device.setDefault(device:) with task-scoped
  Device.withDefaultDevice(.cpu, body:); wrap both load and generate so the
  TaskLocal propagates through ModelContainer.perform
This commit is contained in:
link2026
2026-05-25 23:18:08 +08:00
parent 53da442424
commit e4a68a1bdd
3 changed files with 67 additions and 57 deletions

View File

@@ -1,6 +1,6 @@
import Foundation
enum ModelKind: String, CaseIterable {
nonisolated enum ModelKind: String, CaseIterable {
/// HuggingFace mlx-community , Models/
case llm = "Qwen3-1.7B-4bit"
case vl = "Qwen2.5-VL-3B-Instruct-4bit"
@@ -21,10 +21,10 @@ enum ModelKind: String, CaseIterable {
/// `@unchecked Sendable`:rootURL let, filesystem(线),
/// actor / Task 访
/// `nonisolated(unsafe) shared`: `-default-isolation=MainActor`
/// static MainActor , actor 访 await opt-out
/// `nonisolated`: `SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor`,
/// MainActor, `AIRuntime` actor
final class ModelStore: @unchecked Sendable {
nonisolated(unsafe) static let shared: ModelStore = {
nonisolated static let shared: ModelStore = {
do {
let appSupport = try FileManager.default.url(
for: .applicationSupportDirectory,
@@ -46,16 +46,16 @@ final class ModelStore: @unchecked Sendable {
try FileManager.default.createDirectory(at: rootURL, withIntermediateDirectories: true)
}
func localURL(for kind: ModelKind) -> URL {
nonisolated func localURL(for kind: ModelKind) -> URL {
rootURL.appendingPathComponent(kind.rawValue, isDirectory: true)
}
func isReady(_ kind: ModelKind) -> Bool {
nonisolated func isReady(_ kind: ModelKind) -> Bool {
let sentinel = localURL(for: kind).appendingPathComponent(kind.sentinelFilename)
return FileManager.default.fileExists(atPath: sentinel.path)
}
func totalBytes(for kind: ModelKind) -> Int {
nonisolated func totalBytes(for kind: ModelKind) -> Int {
let folder = localURL(for: kind)
guard let enumerator = FileManager.default.enumerator(
at: folder,
@@ -71,7 +71,7 @@ final class ModelStore: @unchecked Sendable {
}
/// Demo : Bundle (W6 使,)
func seedFromBundle(_ kind: ModelKind) throws {
nonisolated func seedFromBundle(_ kind: ModelKind) throws {
guard let bundleURL = Bundle.main.url(forResource: kind.rawValue, withExtension: nil) else {
#if DEBUG
assertionFailure("Bundle 缺少 \(kind.rawValue),检查资源是否加入 target")