Context:
The docs for CIImage explicitly declare it safe to use across threads:
CIContext and CIImage objects are immutable, which means each can be shared safely among threads. Multiple threads can use the same GPU or CPU CIContext object to render CIImage 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.)