【问题标题】:Why does Swift UITableViewController template use optionals arguments in tableView cellForRowAtIndexPath method?为什么 Swift UITableViewController 模板在 tableView cellForRowAtIndexPath 方法中使用可选参数?
【发布时间】:2014-07-27 12:39:33
【问题描述】:

如果你创建新的 UITableViewController 类,你会看到重写的注释方法:

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

    // Configure the cell...

    return cell
}
*/

你可以取消注释方法,它不会因为错误而工作

'UITableView?' does not have a member named 'dequeueReusableCellWithIdentifier'

原因是:tableView 被定义为可选类型 "UITableView?" 并且你必须在调用该方法之前解开 tableView。比如这样:

let cell = tableView!.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)

但我们可以让它们隐式解包选项并在没有的情况下使用tableView!

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

问题是:为什么 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?

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

let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell

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

/*
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
}
*/

【问题讨论】:

  • 这是在 beta 2 中修复的 :)
  • 没有 Swift 方面的专家,但上面的方法不适用于 XCode 6 GM。我不得不使用“覆盖 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { ” 来构建我的项目。

标签: ios xcode uitableview swift


【解决方案1】:

其实这是使用委托方法的正确方式。

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

}

【讨论】:

  • 为什么是cell_?看不到命名约定背后的原因。
  • @Zorayr 这根本没有意义。从未见过 Apple 在 任何 类或结构中这样做。
  • @Zorayr 从我的项目中复制时,我没有编辑名称。出于某种原因,这是一个私有值。
  • 非常不快速。是的,un-Swiftish 是一个词。
  • 这修复了我在使用标准方法快速 dequeueReusableCellWithIdentifier 时遇到的间歇性错误访问异常。
【解决方案2】:

是的,这很奇怪。事实上,如果你删除模板提供的方法并开始键入它们中的每一个,Xcode 自动补全将建议具有隐式展开的可选参数的方法,例如

tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!

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

有关讨论的更多信息,请参阅this question

【讨论】:

  • 嗯...这很有趣。可能是因为 XCode 6 的 beta 状态。但这不是第一次默认 xcode 模板令人困惑。另一个例子是带有情节提要的项目中的方法“init(style: UITableViewStyle)”会导致错误。他们可以将 init(coder aDecoder: NSCoder!) 方法添加到默认模板中,该方法适用于情节提要或不添加任何内容。 XCode 5 稳定版也是如此。
  • 是的。实际上,我在使用 IB 测试 UITableViewController 子类来回答这个问题时遇到了它。
猜你喜欢
  • 2017-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-23
  • 1970-01-01
相关资源
最近更新 更多