So far I understood, that setting approachable concurrency means non-isolated async for all functions by default, so when I call an async function from the main actor, it gets executed on the main actor.
Now, I’m adding @concurrent to an async method, to make it run on a new thread off the main actor, right?
So when I added @concurrent to my method:
@concurrent
func loadModels() async {
let model = try? await YoloModel()
await MainActor.run {
self.model = model
self.areModelsLoaded = true
}
}
I noticed
- the heavy loading of the CoreML model still happens on the main thread and my SwiftUI gets slow even though the
loadModels()should run on a background thread - why do I even have to do
await YoloModel()? withoutawaitthe compiler complains:
Main actor-isolated initializer 'init(configuration:)' cannot be called from outside of the actor; this is an error in the Swift 6 language mode
Now, the auto-generated swift file for the CoreML model doesn't have any asyncs, nor is it marked @MainActor. Is it possible that the approachable concurrency makes it implicitly only initialize on the main thread? How can I load it off the main thread?
//
// YoloModel.swift
//
// This file was automatically generated and should not be edited.
//
import CoreML
/// Class for model loading and prediction
@available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, visionOS 1.0, *)
class YoloModel {
let model: MLModel
// ....
convenience init(configuration: MLModelConfiguration = MLModelConfiguration()) throws {
try self.init(contentsOf: type(of:self).urlOfModelInThisBundle, configuration: configuration)
}