如何修复“致命错误:在使用tableview.reloaddata时隐式展开一个可选值时意外发现nil”

时间:2019-05-22 05:49:34

标签: swift macos

我正在创建一个使用NSOpenPanel且链接到文件->打开...菜单的应用程序。当用户选择.txt文件时,程序会读取该文件,并将其值添加到现有的字符串数组中,然后应将数据重新加载到TableView中。但是当我在运行时调用tableview.reloaddata()时,它给了我以下错误:Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

这是我的AppDelegate.swift文件的代码:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    let vc = ViewController(nibName: "ViewController", bundle: nil)

    func applicationDidFinishLaunching(_ aNotification: Notification) {
    // Insert code here to initialize your application
    }

    func applicationWillTerminate(_ aNotification: Notification) {
    // Insert code here to tear down your application
    }

    func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
    return true
    }

    @IBAction func openUnFichier(_ sender: NSMenuItem) {
        let fichierPanel: NSOpenPanel = NSOpenPanel()
        fichierPanel.allowsMultipleSelection = false
        fichierPanel.canChooseFiles = true
        fichierPanel.canChooseDirectories = false
        fichierPanel.allowedFileTypes = ["txt"]
        let response = fichierPanel.runModal()
        if response == NSApplication.ModalResponse.OK{
            guard let selectedURL = fichierPanel.url else{return}
            do{
                var fullDocument = try String(contentsOf: selectedURL, encoding: String.Encoding.utf8)
                print(type(of: fullDocument))
                var lines : [String] = fullDocument.components(separatedBy: "\n" as String)
                for line in lines {
                    vc.test_data.append(line)
                    print(type(of: vc.test_data))
                }
                } catch let error as NSError{
                    print("Erreur!!!!!!! \(error)")
                }
            vc.tableView.reloadData() //IT CRASHES HERE
         }else {

        }
    }
 }

这是我的ViewController.swift的代码:

import Cocoa
import WebKit

class ViewController: NSViewController, NSTableViewDataSource{

    public var test_data = ["https://www.youtube.com/watch?v=0AQFQMeOAig", "https://www.youtube.com/watch?v=domoD_w3uFw"]
    var test_text = ""
    var nextUrl = ""

    //func

    func refresh(){
        tableView.reloadData()
    }

    @IBAction func plus(_ sender: NSButton) {
        if urlInput.stringValue == "" {

        } else {
        test_text = urlInput.stringValue
        test_data.append(test_text)
        urlInput.stringValue = ""
        tableView.reloadData()
        // fonction du bouton +
        }
    }

    @IBAction func nextLien(_ sender: NSButton) {
        if test_data == [] {

        } else {
        nextUrl=test_data[0]
        var monUrl = URL(string: nextUrl)
        var maRequete = URLRequest(url: monUrl!)
        view_web.load(maRequete)
        test_data.remove(at: 0)
        tableView.reloadData()
        //fonction du bouton pour le prochain lien
        }
    }

    func numberOfRows(in tableView: NSTableView) -> Int {
        return test_data.count
    }

    func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
        return test_data[row]
    }

    //var

    @IBOutlet weak var urlInput: NSTextField!

    @IBOutlet weak var view_web: WKWebView!

    @IBOutlet weak var tableView: NSTableView!


    //func vitale

    override func viewDidLoad() {
        super.viewDidLoad()

        let myURL = URL(string: "https://www.youtube.com")
        let myRequest = URLRequest(url: myURL!)
        view_web.configuration.preferences.plugInsEnabled = true
        view_web.load(myRequest)
        // Do any additional setup after loading the view.
    }
}

我不了解的是,viewtable.reloaddata()在ViewController.swift文件中工作正常,但是当我尝试在AppDelegate文件中进行操作时,相同的指令不起作用。

我确实检查了我的字符串数组(test_data)是否为空。 (在我加载并提取自己创建的“ .txt”文件的数据后,它包含4个元素。)

我想知道如何解决此错误,以便在解析txt文件后在TableView中显示数据。

非常感谢您。

1 个答案:

答案 0 :(得分:0)

有一个简单的解决方案:将IBAction移至视图控制器。

  • 在Interface Builder中,从IBAction断开AppDelegate
  • openUnFichier方法移至ViewController(在AppDelegate中删除)。
  • 在Interface Builder中,将菜单项连接到First Responder(红色立方体),然后在列表中选择openUnFichier。实现该方法的响应者链中的第一类将执行该方法。