How can you deallocate no-longer-needed NSLayoutConstraint objects that were programmatically created, to avoid a memory leak?

Something I find odd is once you create a constraint, the view hangs onto it forever, even if you explicitly remove it from the view's constraints collection (or set it's isActive to false which does so implicitly.) This is regardless of if you yourself are hanging onto the reference, meaning if you let go of an inactive constraint, you have a memory leak... at least until the view itself is deallocated.

Worse, if you're hanging onto that constraint with a weak var, after the view is deallocated, instead of the weak var going to nil as one would expect, if you try to even look at it, you outright crash.

Here's some Playground code to demonstrate the above.

Code Block
weak var view = UIView()
print(view ?? "No view")
// As expected, prints 'No view' since the view is created, then instantly deallocated.
var view2:UIView? = UIView()
weak var constraint = view2!.widthAnchor.constraint(equalToConstant: 100)
print(constraint ?? "No constraint")
// Prints '<NSLayoutConstraint:0x600003e0c140 UIView:0x7faa875079f0.width == 100 (inactive)>'
// This *isn't* expected since nothing should be holding the reference.
constraint?.isActive = false // Technically already false, but just checking
print(constraint ?? "No constraint")
// Prints '<NSLayoutConstraint:0x600003e0c140 UIView:0x7faa875079f0.width == 100 (inactive)>'
view2!.removeConstraint(constraint!) // Again, technically not in here, but being explicit
print(constraint ?? "No constraint")
// Prints '<NSLayoutConstraint:0x600003e0c140 UIView:0x7faa875079f0.width == 100 (inactive)>'
view2 = nil // This is the only thing that kills the constraint, but...
print(constraint ?? "No constraint") // This results in an outright crash


That last line resulted in...

error: Execution was interrupted, reason: EXCBADACCESS (code=EXCI386GPFLT).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.

So how does one properly clean up constraints that are no longer needed?

Side-note: Looks like the 'live preview' here is broken. When editing, *all* my code after the first comment appears commented out, but when I finish editing, it's displayed correctly. Drove me mad trying to figure out why my code wasn't displaying properly. Nice little waste of five minutes there.
I’m not an expert in how Swift optimizes its memory management. But if you put that first assignment to constraint inside an
Code Block
autoreleasepool { }
then it is nil right away as expected. Perhaps in your sample it doesn’t get cleaned up until the next run loop iteration.
How can you deallocate no-longer-needed NSLayoutConstraint objects that were programmatically created, to avoid a memory leak?
 
 
Q