MTKTextureLoader crashes when passing a CGImage

I'm trying to resize an UIImage before I create a MTLTexture, so I first started by checking if I could initialize a MTLTexture with the CGImage obtained from the UIImage, but it always crashes with a EXC_BAD_ACCESS.


This is the code that loads a UIImage,


extension MTKTextureLoader {
    func newTexture(with uiImage: UIImage, options: [String : NSObject]? = nil, completionHandler: @escaping MTKTextureLoaderCallback) {
        if let cgImage = uiImage.cgImage {
            return self.newTexture(with: cgImage, options: options, completionHandler: completionHandler)
        } else {
            completionHandler(nil, TextureError.CouldNotBeCreated)
        }
    }
}


And while this code crashes,

if let uiImage = UIImage(contentsOfFile: cachedFileURL.path) {
  return self.newTexture(with: uiImage, options: options, completionHandler: completionHandler)
}


this one works perfectly fine,

return self.newTexture(withContentsOf: cachedFileURL, options: options, completionHandler: completionHandler)


Shouldn't they just do the same thing?

Any ideas?


The call stack of the crash for reference,

Thread 5Queue : com.apple.mtktextureloaderload (concurrent)
#0
0x00000001874705cc in IIOImageProviderInfo::copyImageBlockSetWithOptions(CGImageProvider*, CGRect, CGSize, __CFDictionary const*) ()
#1
0x000000018746e640 in IIOImageProviderInfo::CopyImageBlockSetWithOptions(void*, CGImageProvider*, CGRect, CGSize, __CFDictionary const*) ()
#2
0x0000000197035e2c in -[MTKTextureLoaderImageIO decodeCGImageImageProvider:CGImageProvider:options:] ()
#3
0x0000000197035cfc in -[MTKTextureLoaderImageIO decodeCGImage:options:] ()
#4
0x0000000197035b4c in -[MTKTextureLoaderImageIO initWithCGImage:options:error:] ()
#5
0x0000000197032a40 in -[MTKTextureLoader _loadCGImage:options:completionHandler:] ()
#6
0x00000001970313d0 in __68-[MTKTextureLoader newTextureWithCGImage:options:completionHandler:]_block_invoke ()
#7
0x0000000100f65258 in _dispatch_call_block_and_release ()
#8
0x0000000100f65218 in _dispatch_client_callout ()
#9
0x0000000100f71334 in _dispatch_continuation_pop ()
#10
0x0000000100f70fa8 in _dispatch_async_redirect_invoke ()
#11
0x0000000100f74e2c in _dispatch_root_queue_drain ()
#12
0x0000000100f74b78 in _dispatch_worker_thread3 ()
#13
0x000000018482b2a0 in _pthread_wqthread ()
#14
0x000000018482ad8c in start_wqthread ()
Enqueued from NSOperationQueue 0x170222f00 :: NSOperation 0x17024c540 (QOS: DEFAULT) (Thread 18)Queue : NSOperationQueue 0x170222f00 :: NSOperation 0x17024c540 (QOS: DEFAULT) (serial)
#0
0x0000000100f70b30 in _dispatch_queue_push ()
#1
0x0000000197031388 in -[MTKTextureLoader newTextureWithCGImage:options:completionHandler:] ()
#2
0x0000000100082900 in MTKTextureLoader.newTexture(with : UIImage, options : [String : NSObject]?, completionHandler : (MTLTexture?, Error?) -> ()) -> () at /Users/david/projects/InstaVR/instavr-ios-sdk/instavr-ios-sdk/sdk/gfx/prims/Texture.swift:146

Replies

Well, whatever you're doing, MetalKit ir ImageiIO shouldn't crash. Have you created a bugreport at https://bugreport.apple.com?

That crashes because uiImage was dealloced while processing the cgImage from uiImage. You need to hold a strong reference of uiImage until completionHandler called.