为什么Swift UITableViewController模板在tableView cellForRowAtIndexPath方法中使用optionals参数?

Joh*_*kon 25 xcode uitableview ios swift

如果您创建新的UITableViewController类,您将看到用于覆盖的注释方法:

/*
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
    let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)

    // Configure the cell...

    return cell
}
*/
Run Code Online (Sandbox Code Playgroud)

您可以取消注释方法,但由于错误,它将无法工作

'UITableView?' does not have a member named 'dequeueReusableCellWithIdentifier'
Run Code Online (Sandbox Code Playgroud)

原因是:tableView被定义为可选类型" UITableView? ",你必须在调用方法之前解包tableView.例如这样:

let cell = tableView!.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
Run Code Online (Sandbox Code Playgroud)

但我们可以让它们隐式解包,并且不使用tableView !

override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
    return cell
}
Run Code Online (Sandbox Code Playgroud)

问题是:为什么xcode将它们定义为可选项?是否有任何理由或优势与隐含的未解决的期权?我们可以肯定,这种方法总是得到非零值吗?

我们还会有另一个错误

Constant 'cell' inferred to have type 'AnyObject!', which may be unexpected
Type 'AnyObject!' cannot be implicitly downcast to 'UITableViewCell'; did you mean to use 'as' to force downcast?
Run Code Online (Sandbox Code Playgroud)

我们可以通过添加UITableViewCell来修复它,如下所示:

let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell
Run Code Online (Sandbox Code Playgroud)

我不知道为什么默认情况下模板看起来不像这样:

/*
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
    let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell //or your custom class

    // Configure the cell...

    return cell
}
*/
Run Code Online (Sandbox Code Playgroud)

Rya*_*yan 22

实际上这是使用委托方法的正确方法.

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("CELL_ID", forIndexPath: indexPath)
    cell.textLabel.text = "aaaa"
    return cell

}
Run Code Online (Sandbox Code Playgroud)


Cez*_*zar 17

是的,这很奇怪.事实上,如果你删除模板提供的方法并开始键入每个方法,Xcode自动完成将建议使用隐式解包的可选参数的方法,如

tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
Run Code Online (Sandbox Code Playgroud)

我猜模板目前是错误的,可能会在以后修复,因为在手动输入时甚至没有建议模板版本.如果你将它们留在那里,它们会被正常调用,只要你根据需要正确地打开参数,它就会起作用.

有关讨论的更多信息,请参阅此问题.