【问题标题】:"fatal error" when calling tableView.reloadData(), the tableView is properly connected调用 tableView.reloadData() 时出现“致命错误”,tableView 连接正确
【发布时间】:2017-12-04 04:23:09
【问题描述】:

我正在尝试在程序运行时动态更新tableView。我相信我已经更新了正确加载数据的数组,但是当我按下调用 self.eventTable.reloadData() 的按钮时,我收到错误:

fatal error: unexpectedly found nil while unwrapping an Optional value

以下是相关代码:

视图控制器:

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

//Timer view
@IBOutlet weak var playButton: UIBarButtonItem!;
@IBOutlet weak var pauseButton: UIBarButtonItem!;
@IBOutlet weak var refreshButton: UIBarButtonItem!;
@IBOutlet weak var timerLabel: UILabel!

var counter = 0
var timer = Timer()
var isTimerRunning = false

//testing view container
var viewShowing = 1;

override func viewDidLoad() {

    // Do any additional setup after loading the view, typically from a nib.
    pauseButton.isEnabled = false

    hideAll();
    self.basicContainer.isUserInteractionEnabled = true;
    self.basicContainer.isHidden = false;

    self.timerLabel.text = String("00:00:00");

    eventTable.dataSource = self
    eventTable.delegate = self

    super.viewDidLoad()        
    loadEvents(event: "timer start")
}

...

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


// Add table to keep track of events
@IBOutlet weak var eventTable: UITableView!

var eventData = [Session]()

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return eventData.count;
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellReuseIdentifier") as! eventTableViewCell
    let event = eventData[indexPath.row]
    cell.eventLabel.text = event.session
    return cell
}

private func loadEvents(event: String) {
    guard let event1 = Session(session: event) else {
        fatalError("Unable to instantiate event")
    }

    eventData += [event1]

    DispatchQueue.main.async() {
        self.eventTable.reloadData()
    }
}

func testPrint() {
    loadEvents(event: "testing cell adding")
    //self.eventTable.reloadData()
    viewWillAppear(false)
    print("This is a test print");
}

}

该函数在ViewDidLoad() 中调用时可以正常工作,但在另一个类中的按钮调用时则无法正常工作(“这是一个测试打印”打印到控制台,所以我知道按钮调用正在执行)。

预期的行为是 tableView (eventTable) 重新加载显示两个单元格,“计时器启动”和“测试单元格添加”(理想情况下,“测试单元格添加”位于顶部)。

还要强调一下,eventTable 是连接到storyboard的,这似乎是这里的通病。

这里是Session.swift 文件和eventTableViewCell.swift 文件(如果有帮助的话):

Session.swift

import Foundation
import UIKit

class Session {

//MARK: Properties

var session: String

//MARK: Initialization

init?(session: String) {

    guard !session.isEmpty else {
        return nil
    }

    self.session = session
}

}

eventTableViewCell.swift

import Foundation
import UIKit

class eventTableViewCell: UITableViewCell {
//MARK: Properties
@IBOutlet weak var eventLabel: UILabel!

override func awakeFromNib() {
    super.awakeFromNib()
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)
    // Configure the view for the selected state
}

}

谢谢!

编辑:我调用 testPrint() 的 ViewController。

import UIKit

class BasicViewController: UIViewController {

var VC = ViewController();


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

//Basic buttons
@IBOutlet weak var warmButton: UIButton!
@IBOutlet weak var dryButton: UIButton!
@IBOutlet weak var stimulateButton: UIButton!
@IBOutlet weak var controlButton: UIButton!
@IBOutlet weak var bedButton: UIButton!
@IBOutlet weak var tempButton: UIButton!
@IBOutlet weak var pulseButton: UIButton!
@IBOutlet weak var ecgButton: UIButton!
@IBOutlet weak var apgarButton: UIButton!
@IBOutlet weak var helpButton: UIButton!

//APGAR options
@IBOutlet weak var skinColor: UIButton!
@IBOutlet weak var pulse: UIButton!
@IBOutlet weak var grimace: UIButton!
@IBOutlet weak var flexion: UIButton!
@IBOutlet weak var respiratoryEffort: UIButton!



@IBAction func warmButton(sender: AnyObject) {
    VC.testPrint();
}   
}

您似乎可以说我正在实例化一个导致问题的新 ViewController。我应该如何解决这个问题?对 Swift 相当陌生

【问题讨论】:

  • 你在哪里从其他类调用这个函数?
  • 永远不要自己调用视图控制器生命周期事件,例如viewWillAppear
  • 正如@3stud1ant3 询问的那样,您在哪里处理按钮点击以及如何调用该函数。您可能正在实例化视图控制器的新实例,该实例未连接到情节提要场景,因此您的表格视图为零
  • 发布您正在调用 loadEvents 函数以重新加载 tableview 的另一个类的代码。
  • @Paulw11 感谢您的建议,您似乎是对的。与其他班级一起编辑了帖子。在主/父 ViewController 中引用函数的最佳方式是什么?

标签: ios swift uitableview swift3 reloaddata


【解决方案1】:

我认为,您的问题出在这几行代码中:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellReuseIdentifier") as! eventTableViewCell
    let event = eventData[indexPath.row]
    cell.eventLabel.text = event.session
    return cell
}
  • 您能否检查单元格标识符是否与您的单元格标识符相同
  • eventData 数组中的行数

【讨论】:

  • ...和eventLabel outlet 设置正确(参考not nil
  • 我不认为这是问题所在。此函数在 viewDidLoad() 中第一次调用时工作正常,只有在按下按钮时第二次调用时才会出现问题。
  • 使用if letguard 语句来解开可选值并放置断点并找出实际错误出现的位置。
猜你喜欢
  • 1970-01-01
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-02
相关资源
最近更新 更多