The app crashes with Thread 1: EXCBADINSTRUCTION (code=EXCI386INVOP, subcode=0x0)
when I add the instance of the below mentioned view as subview to any VC's view.
Reason : the lblContainer gets deallocated after being assigned by a local var object .
The crash doesn't reproduce when I use a let variable to create the view and assign it to lblContainer.
Also the crash happens only in the optimised builds compiled with Xcode version above 11.3.
The optimisation settings are :
Apple CLang Code Generation
Optimization Level: Fastest, Smallest [-Os]
Swift Compiler - Code Generation
Optimization Level: Optimize for speed [-O]
You can find my sample project here
Could anyone please explain this behaviour to me ?
when I add the instance of the below mentioned view as subview to any VC's view.
Reason : the lblContainer gets deallocated after being assigned by a local var object .
The crash doesn't reproduce when I use a let variable to create the view and assign it to lblContainer.
Code Block class HorizontalViewMore: UIView { private weak var lblContainer : UIView! override init(frame: CGRect) { super.init(frame: frame) createViews() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func createViews() { //it crashes only when the object is declared as var not let var view : UIView = UIView.init(frame: CGRect.zero) self.lblContainer = view; self.lblContainer.isUserInteractionEnabled = false //it often crashes here with //Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) self.lblContainer.translatesAutoresizingMaskIntoConstraints = false; self.addSubview(self.lblContainer) self.lblContainer.backgroundColor = UIColor.clear; self.lblContainer.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true; self.lblContainer.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true; self.lblContainer.leftAnchor.constraint(greaterThanOrEqualTo: self.leftAnchor, constant: 8.0).isActive = true self.lblContainer.rightAnchor.constraint(lessThanOrEqualTo: self.rightAnchor, constant: -8.0).isActive = true } deinit { print("MemTest : HorizontalViewMore is deinitialized") } }
Also the crash happens only in the optimised builds compiled with Xcode version above 11.3.
The optimisation settings are :
Apple CLang Code Generation
Optimization Level: Fastest, Smallest [-Os]
Swift Compiler - Code Generation
Optimization Level: Optimize for speed [-O]
You can find my sample project here
Could anyone please explain this behaviour to me ?
Thanks for testing.it doesn't crash if I change the line 32
In optimized code, local variables may be released at any time where the values will not be used any more.Could anyone please explain this behaviour to me ?
Of course this applies to both var and let, but what affects this behavior is sort of implementation details and you should better not rely on some specific implementation.
In your original code shown, the local variable view (which holds a strong reference to the UIView) is never used after line 24.
Thus, if optimizer decided to release the variable there, there's no strong reference to the UIView. A weak reference to it gets nil, and bang.
In some implementations of compilers or slight changes other than var to let might generate a code which works as you expect,
but generally, you should keep strong reference to an instance explicitly while it is needed.