Hello,
I'm seeing this on a Swift 2 app compiled with Xcode 7 GM running on iOS 9 GM. I believe the same behaviour is seen on Swift 1.2 apps compiled for iOS 8 when running on iOS 9 (the behaviour does not reproduce on iOS 8, though).
The leak seems to be external to my application as the Memory Report on Xcode shows the memory for "Other Processes" growing to the point where there is a Memory Warning and the application is terminated. The memory of the App itself remains stable. I have not been able to detect any leak using Instruments.
I have been commenting out parts of my code and it seems that the leak happens everytime this line is called:
let outputCGImage = self.ciContext.createCGImage(output, fromRect: input.extent)
I have tried a few things to prevent the leak, with no success:
1.- I'm not able to do CGImageRelease of outputCGImage as those objects are automatically managed.
2.- I have tried to call that line on an autoreleasepool block.
3.- I have tried to call that line from the Main Thread (originally it is called on a background thread).
4.- I have tried to destroy and recreate ciContext hoping to release the memory leaked.
Nothing has helped.
Any ideas about what is going here? I really doubt this is a bug on iOS 9 GM as I believe it is very noticeable, but I can't really tell what is wrong with my code.
Additionally any ideas on how to properly debug this kind of external leaks would be appreciated too.
Thanks a lot!
UPDATE: Destroying and recreating the EAGLContext used with the CIContext brings back the memory. Obviously this is not a solution as re-creating the context everytime a render is needed is very expensive, but I think it gives a hint on where the problem might be.
It looks like they fixed this in 9.1b3. If anyone needs a workaround that works on iOS 9.0.x, I was able to get it working with this:
extension CIContext {
func createCGImage_(image:CIImage, fromRect:CGRect) -> CGImage {
let width = Int(fromRect.width)
let height = Int(fromRect.height)
let rawData = UnsafeMutablePointer<UInt8>.alloc(width * height * 4)
render(image, toBitmap: rawData, rowBytes: width * 4, bounds: fromRect, format: kCIFormatRGBA8, colorSpace: CGColorSpaceCreateDeviceRGB())
let dataProvider = CGDataProviderCreateWithData(nil, rawData, height * width * 4) {info, data, size in UnsafeMutablePointer<UInt8>(data).dealloc(size)}
return CGImageCreate(width, height, 8, 32, width * 4, CGColorSpaceCreateDeviceRGB(), CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue), dataProvider, nil, false, .RenderingIntentDefault)!
}
}