Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 3 weird crashes (type inference)

Tags:

ios

swift

swift3

I couldn't find a more appropriate title for this. This is the scenario:

final class Something : UIViewController {
    fileprivate var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView = UITableView(frame: CGRect.zero, style: .plain)
        self.tableView.translatesAutoresizingMaskIntoConstraints = false
        //Delegate, register cell, ...

        self.view.addSubview(self.tableView)
        let views/*: [String: Any]*/ = ["table": self.tableView]

        //THIS LINE NOW WILL CRASH
        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|-0-[table]-0-|", options: [], metrics: nil, views: views))
        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[table]-0-|", options: [], metrics: nil, views: views))
    }
}

EDIT: If you don't put an explicit type annotation the compiler will infer [String: UITableView?] in this particular case.

Now if I don't explicitly let the compiler know that views are of type [String: Any] (like the commented out thingie) this code crashes and I get a neat little crash giving me a middle finger along with this message:

-[_SwiftValue nsli_superitem]: unrecognized selector sent to instance 0x60000044a560

Things like this are happening all over the place after migrating from Swift 2.x. Can someone please shed some light on the subject? Why is this happening? How to avoid things like this? How do discover origins of such crashes (some are very hard to track down)?

like image 523
Majster Avatar asked Oct 03 '16 08:10

Majster


1 Answers

This is a issue with Swift 3.

Declare the dictionary explicitly:

let views: [String:UIView] = ["table":self.tableView]

In you're case when you create in this manner let views = ["table": self.tableView] you receive type that is [String:UIView?] and the optional value is the main problem.

Usage of the Any and AnyObject.

Swift provides two special types for working with nonspecific types:

Any can represent an instance of any type at all, including function types.

AnyObject can represent an instance of any class type.

like image 193
Oleg Gordiichuk Avatar answered Oct 15 '22 08:10

Oleg Gordiichuk