TL;DR: I have an IBOutlet (UILabel) that is properly connected in Storyboard. Accessing (unwrapping) it works fine in viewDidLoad() ... but a few seconds later its value is nil. A watchpoint says that the outlet changes right after a call to viewDidLayoutSubviews(), but... a print() call at the end of viewDidLayoutSubviews() shows it non-nil.
This is very similar to IBOutlet is nil but his solution (track value with didSet()) did not work. (There are many related posts but all had trivial solutions.)
What I have done:
- Reconnected the outlet to the Label — from both sides
- Deleted the Label and reconnected it
- Cleaned the project
- Deleted the DerivedData
- Quit and restarted Xcode
- Quit and restarted my Mac
- Added a
didSet()method to the outlet.- It triggers during
viewDidLoad()and shows a non-nil value. - In
viewDidLoad()I set its text value with no problem - It does not trigger before the nil-unwrapping crash
- It triggers during
- Added a watchpoint to the variable.
- This does trigger before crash (right after
viewDidLayoutSubviews()and shows the following:
- This does trigger before crash (right after
As mentioned before, at exit of the most recent method call before the watchpoint (viewDidLayoutSubviews()) the outlet is non-nil.
These crashes seem always to involve subviews of a particular superview. I added a watchpoint to the superview's outlet but it never triggers.
What could be inciting my code to let go of this weak reference?

TL;DR: I was clobbering the relevant views.
Well, the best way to find your own answer is to ask someone else. Thanks to @DonMag, I was preparing more traces, breakpoints, and screen shots. I noticed this method (added to fix another bug, of course):
Of course, the two views that were becoming nil were subviews of
centralOverlay. Ones I wanted to keep.So I guess my answer was similar to that of IBOutlet is nil — pilot error — except the
didSet()handler did not solve the mystery.