Moving to Swift 5.6 (with the latest Xcode 13.3), some code broke at runtime.
This is the function:
func outputImage(extent inext: CGRect? = nil, params: [Any], roiCallback roi: CIKernelROICallback? = nil) -> CIImage? {
let roi: CIKernelROICallback = roi ?? self.roiCallback ?? Self.identityRoiCallback
switch kind {
case .generic:
if let im = params.first, let image = im as? CIImage {
let extent: CGRect = inext ?? image.extent
return genericKernel.apply(extent: extent, roiCallback: roi, arguments: params)
} else if let im = params.first, let sampler = im as? CISampler {
let extent: CGRect = inext ?? sampler.extent
return genericKernel.apply(extent: extent, roiCallback: roi, arguments: params)
} else { return nil }
case .color:
if let im = params.first, let image = im as? CIImage {
let extent: CGRect = inext ?? image.extent
let res2: CIImage? = colorKernel.apply(extent: extent, arguments: params)
return res2
}
else { return nil }
case .blend:
if params.count == 2, let im = params.first, let image = im as? CIImage,
let image2 = params[1] as? CIImage {
let res = blendKernel.apply(foreground: image, background: image2)
return res
}
else { return nil }
case .warp:
if let im = params.first, let image = im as? CIImage {
let extent: CGRect = inext ?? image.extent
let res = warpKernel.apply(extent: extent, roiCallback: roi, image: image, arguments: Array(params.suffix(from: 1)))
return res
}
else { return nil }
}
}
with
private let roiCallback: CIKernelROICallback?
static let identityRoiCallback: CIKernelROICallback = { (index, rect) -> CGRect in
return rect
}
Specifically, the program receives a systematic EXC_BAD_ACCESS
on return res2
(under .color case). This code was running apparently fine on Swift 5.5 and earlier. After investigation, changing the way the roi
let variable is defined can solve the problem:
let roi: CIKernelROICallback = (roi ?? self.roiCallback) ?? Self.identityRoiCallback
that is, parentheses for the first 2 works (last 2 still fails). There are other constructs that also work.
Are there any changes in Swift 5.6 that could explain that? A mix-up between closure and functions maybe? It sounds like a compiler bug, or am I not using it as expected?
Thank you.