Search code examples
iosswiftmacosmetal

Metal Device (MTLDevice) variable becomes nil after initialization


I have a renderer class in my Metal Swift (iOS/MacOS) project that is an MTKViewDelegate. I extract the MTLDevice using MTLCreateSystemDefaultDevice(), however after init, it becomes nil? I wonder if I've missed a quirk of Swift or Metal here. This is roughly how the code goes,

class Renderer: NSObject, MTKViewDelegate {

    var device: MTLDevice!
​
    init(metalView: MTKView) {
        guard let device = MTLCreateSystemDefaultDevice() else
        {
            fatalError("GPU not available")
        }
​        metalView.device = device
        if device != nil {
            print (“device not nil”)
        }
    }
​
    func draw(in view: MTKView) {
        if device == nil {
            print (“device is nil here”)
        }
    }
}

In my ViewController I do

guard let metalView = view as? MTKView else {
   fatalError("Metal View not setup")
}
renderer = Renderer(metalView: metalView)

What I see happen is:

device not nil
device is nil here
device is nil here
device is nil here
device is nil here

at 60hz on every draw call

EDIT: Edited code to make it clear that the device actually is being assigned to a variable in the global scope (metalView).


Solution

  • As per your code you are not assigning local device to implicitly unwrapped global device variable. Assign local device to global one to fix the issue.

    guard let device = MTLCreateSystemDefaultDevice() else
            {
                fatalError("GPU not available")
            }
    self.device = device