Crash when setting up the content view loaded from a NIB

I am trying to understand why I am seeing crash reports for my code that creates a view from a NIB like the code below. The crash occurs when referencing contentView which should have been bound when the NIB was loaded.

Am I missing something here other than checking the result of the loadNibNamed function call?

class MyView: NSView {
    @IBOutlet var contentView: NSView!

    init() {
        super.init(frame: NSRect(x: 0, y: 0, width: 84.0, height: 49.0))
        
        commonInit()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func commonInit() {
        Bundle.main.loadNibNamed("MyView", owner: self, topLevelObjects: nil)
        translatesAutoresizingMaskIntoConstraints = false
        contentView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(contentView)
        contentView.frame = self.bounds
    }

Hi @fmoraes , well I think you should try to move on autolayout constraints and not use explicit frame width o height.

Try for example this arrangement:

class MyView: NSView {

    @IBOutlet var contentView: NSView!

    init() {
            super.init(frame: .zero)
            commonInit()
        }
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
        }
        
        private func commonInit() {
            Bundle.main.loadNibNamed("MyView", owner: self, topLevelObjects: nil)
            addSubview(contentView)
            contentView.translatesAutoresizingMaskIntoConstraints = false
            contentView.topAnchor.constraint(equalTo: topAnchor).isActive = true
            contentView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
            contentView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
            contentView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        }
    
}

In this way you use a pure auto layout constraints approach, and NSView could be used in this way.

override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        let myView = MyView()
        view.addSubview(myView)
        myView.translatesAutoresizingMaskIntoConstraints = false
        myView.widthAnchor.constraint(equalToConstant:84.0).isActive = true
        myView.heightAnchor.constraint(equalToConstant:49.0).isActive = true
        myView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        myView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    }

Please try to check on nib file if arrangements on outlet are correct. Approach with contentView is really useful if you want to use a compositional approach, but now we have SwiftUI that makes this for us.

Attach screenshot with navies layout generate with a label inside your MyView

Bye Rob

I understand the advantages of auto layout and I intend to fix several of these issues as I clean up some of the code. But the main issue is that contentView is nil in these crash reports I got and I was just wondering if there was something that could be going wrong with how the NIB is being loaded.

I will be refactoring this common loading code and adding guard statements to provide better fault information in the future. Maybe it is some out of memory issue or corruption that's the culprit as the NIB and connections are all valid, otherwise I would caught it during development and it would crash for a lot more users.

Hi @fmoraes , well possible causes of contentView nil are outlet not correctly set or wrong nib name call during Bundle.main.loadNibNamed. I'm not sure that with this approach you could have memory issue or corruption, I would suggest to try to double check xib configuration on storyboard.

Bye Rob

@GRALInfo I guarantee that the issue is not with @IBOutlets or wrong Nib name as this would fail every time. I have made that mistake during development and Xcode breaks on those instances.

This is something strange and only affects a very small number of users, mostly on zh_CN locale. I am still perplexed, so short of adding better guard statements to see if I can gleam more information, I don't see anything wrong with the code above.

I was hoping someone had similar experiences and could shed some light.

Hi @fmoraes , if you have some minimal sample project to share could help. It 's ok add a guard statement, but if you are sure about @IBOutlet connection and Nib filename, should never happen.

Bye Rob

You can see some example code here:

https://github.com/HearthSim/HSTracker/tree/3.1.1/HSTracker/UIs/Constructed/ActiveEffects

I changed the code recently to try to find where these failures are coming from but it still puzzles me. I have seen some crash reports with memory corruption, so I have a suspicion it may be related to that or some low memory condition.

Crash when setting up the content view loaded from a NIB
 
 
Q