Context:
The docs for CIImage
explicitly declare it safe to use across threads:
CIContext
andCIImage
objects are immutable, which means each can be shared safely among threads. Multiple threads can use the same GPU or CPUCIContext
object to renderCIImage
objects.
I'm using a CIImage
to generate a checkerboard background. I do the work once:
actor Foo
{
private let checkerboardImage: CIImage
init()
{
let color0 = CIColor(red: 82/255, green: 82/255, blue: 82/255, alpha: 1.0)
let color1 = CIColor(red: 30/255, green: 32/255, blue: 34/255, alpha: 1.0)
guard let checkerboardFilter: CIFilter = CIFilter(name: "CICheckerboardGenerator", parameters: ["inputColor0": color0, "inputColor1": color1, kCIInputCenterKey: CIVector(x: 0, y: 0), kCIInputWidthKey: 50.0]),
let image = checkerboardFilter.outputImage else
{
fatalError("Failed to generate the checkerboard CIImage in \(#file)")
}
checkerboardImage = image
}
}
Then, I use this image in a nonisolated
method:
nonisolated func doWork()
{
if let checkerboardCGImage: CGImage = CIContext().createCGImage(checkerboardImage, from: CGRect(x: 0, y: 0, width: 400, height: 400))
{
// Composite another image on top of the checkerboard background image.
}
}
This produces a warning:
Non-sendable type 'CIImage' in asynchronous access to actor-isolated property 'checkerboardImage' cannot cross actor boundary
Question:
This is just a spurious warning because Apple failed to audit its frameworks for Sendable
conformance, correct? CIImage
is explicitly listed as thread-safe and I'm not passing the CIFilter
(which is explicitly listed as NOT thread-safe).
Adding @preconcurrency
to the Core Image import does nothing (I have yet to find a single case where @preconcurrency actually does something; it seems like Apple just forgot to implement it entirely.)