我在Xcode Playground中的UITableViewController子类实例遇到一个非常奇怪的问题。
我以编程方式在UITableViewCell中注册了两个viewDidLoad,并在cellForRowAt方法中使单元出队:

import UIKit
import PlaygroundSupport

class ViewController: UITableViewController {
  override func viewDidLoad() {
    super.viewDidLoad()
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell1")
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell2")
  }

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 2
  }

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    switch indexPath.row {
    case 0:
      return tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath)
    case 1:
      return tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath)
    default:
      fatalError()
    }
  }
}

let vc = ViewController(style: .plain)
PlaygroundPage.current.liveView = vc



但是游乐场会抛出NSException并显示:
error: Execution was interrupted, reason: signal SIGABRT.
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.

请注意,此代码在带有iPhone模拟器的合法Xcode项目中效果很好。我在这里犯错了,还是一个错误?

我正在使用版本10.3(10G8)。

最佳答案

好奇的错误...

这工作正常:

class ViewController: UITableViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell1")
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell2")
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath)
    }
}

但这崩溃了:
class ViewController: UITableViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell1")
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell2")
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath)
    }
}

唯一的区别在于,崩溃的示例返回了第二个注册单元。

如果交换.register()语句的顺序,则"cell2"有效,并且"cell1"崩溃。

EDIT (编辑2:我们需要分配.delegate.dataSource-可以用loadView()viewDidLoad()完成)

请注意,由于仅注册(和使用)一个单元按原样工作,因此不必设置视图。但是,如果您确实在loadView()中设置了视图,则该代码将在Playground中运行而不会崩溃:
class ViewController: UITableViewController {

    override func loadView() {
        let v = UITableView()
        v.delegate = self
        v.dataSource = self
        self.view = v
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell1")
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell2")
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        switch indexPath.row {
        case 0:
            return tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath)
        case 1:
            return tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath)
        default:
            fatalError()
        }
    }
}

关于ios - Xcode Playground使用简单的UITableViewController代码崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57627404/

10-14 17:39
查看更多