最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ios - Why does Swift's lazy var solve the error: Cannot assign value of type '(HomeViewController) -> ()

programmeradmin3浏览0评论

Below code gives an error:

class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    let tableView = {
        let t = UITableView(frame: .zero, style: .grouped)
        t.dataSource = self
        t.delegate = self
        return t
    }()

    ...
}

Error is:

Cannot assign value of type '(HomeViewController) -> () -> HomeViewController' to type '(any UITableViewDataSource)?'

However, if I change it to lazy var tableView = {}(), then error goes away:

class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    lazy var tableView = {
        let t = UITableView(frame: .zero, style: .grouped)
        t.dataSource = self
        t.delegate = self
        return t
    }()

    ...

}

Why does lazy var solve this error?

Below code gives an error:

class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    let tableView = {
        let t = UITableView(frame: .zero, style: .grouped)
        t.dataSource = self
        t.delegate = self
        return t
    }()

    ...
}

Error is:

Cannot assign value of type '(HomeViewController) -> () -> HomeViewController' to type '(any UITableViewDataSource)?'

However, if I change it to lazy var tableView = {}(), then error goes away:

class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    lazy var tableView = {
        let t = UITableView(frame: .zero, style: .grouped)
        t.dataSource = self
        t.delegate = self
        return t
    }()

    ...

}

Why does lazy var solve this error?

Share Improve this question asked Mar 16 at 16:25 sudoExclamationExclamationsudoExclamationExclamation 8,82610 gold badges51 silver badges120 bronze badges 1
  • You used self too early, it's not possible – Fattie Commented Mar 16 at 18:37
Add a comment  | 

1 Answer 1

Reset to default 5

self cannot be used in property initialisers because they are run before self is fully initialised. The error message produced by this code makes it clear:

class Foo {
    let x = 1
    let y = x + 1 // Cannot use instance member 'x' within property initializer; property initializers run before 'self' is available
}

On the other hand, the initialisers of lazy vars are guaranteed to be run after self has been fully initialised, so you can use self there.

With self being unavailable, the token self resolves to the NSObject method named self. This is an instance method that takes no arguments and returns Self, so normally it would be of type () -> HomeViewController. But in this case, there is no instance to call this instance method on, and you end up accessing the curried form. This is of type (HomeViewController) -> () -> HomeViewController - i.e. a method that takes an instance of HomeViewController, and returns a function that does what the self method would do.

// f is of type (HomeViewController) -> () -> HomeViewController
let f = HomeViewController.`self`

// another example:
// g is of type (String) -> () -> String
let g = String.lowercased
g("ABC") // this expression is of type () -> String
g("ABC")() // this is of type String, and evaluates to "abc"

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论