Skip to content

Instantly share code, notes, and snippets.

@JUSTINMKAUFMAN
Last active September 2, 2019 18:37
Show Gist options
  • Save JUSTINMKAUFMAN/51a40d6e2771d9229dcc629512200202 to your computer and use it in GitHub Desktop.
Save JUSTINMKAUFMAN/51a40d6e2771d9229dcc629512200202 to your computer and use it in GitHub Desktop.
Crash when mutating [UIColor] in a struct on a UIView prior to adding that view as a UIViewController's subview
import UIKit
/**
This code *consistently* crashes when built with
the following Xcode 10.2.1 build settings:
`Swift Version` = `5` (i.e. default)
`Enable Testability` = `NO`
`Optimization Level` = `-Owholemodule`
Download the Xcode project zip here:
http://bit.ly/2JDPb6b
*/
struct ViewModel {
var colors: [UIColor]
init(colors: [UIColor]) {
self.colors = colors
}
}
class CrashView: UIView {
var colors: [UIColor] = []
var model: ViewModel {
didSet { self.colors = model.colors }
}
init() {
self.model = ViewModel(colors: [UIColor.black, UIColor.gray])
super.init(frame: .zero)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
// 2:
accessColors()
}
func accessColors() {
// 3:
print(model.colors)
}
}
class ViewController: UIViewController {
let crashView = CrashView()
override func viewDidLoad() {
super.viewDidLoad()
// 1:
crashView.model.colors = [UIColor.blue, UIColor.green]
view.addSubview(crashView)
}
}
@JUSTINMKAUFMAN
Copy link
Author

JUSTINMKAUFMAN commented Sep 2, 2019

Here is a more minimum repro that doesn’t require views or VCs at all:

struct Stage {
    var backupDancers: [Any] = []
}

class Performance {
    var stage: Stage? = Stage()
    
    func andDaaaaaance() {
        print(stage?.backupDancers.count) // crashes
    }
}

class DanceHall {
    let performance = Performance()
    
    func letsParty() {
        setTheStage()
        performance.andDaaaaaance()
    }
    
    func setTheStage() {
        let randomPerson = NSObject()
        performance.stage?.backupDancers = [randomPerson]
    }
}

@JUSTINMKAUFMAN
Copy link
Author

JUSTINMKAUFMAN commented Sep 2, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment