簡體   English   中英

打開基於NSDocument的應用程序會加載兩個窗口

[英]Opening NSDocument based app loads two windows

我有一個簡單的基於NSDocument的應用程序,它具有兩個文本字段(想象一下git不同)。 當我打開文件時,它會打開兩個帶有文件名的窗口。 在第一個窗口上,一切都很好。 第二個用戶界面為空,具有相同的文件名。

override func makeWindowControllers() {
    // Returns the Storyboard that contains your Document window.
    let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
    let windowController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("Document Window Controller")) as! NSWindowController
    self.addWindowController(windowController)
}

override func read(from data: Data, ofType typeName: String) throws {

    if let fileString = String(data: data, encoding: String.Encoding.utf8) {

        makeWindowControllers()

        guard let vc = windowControllers.first?.contentViewController as? ViewController else {
            throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
        }

        guard let inputString = String(data: data, encoding: .utf8) else {
            throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
        }

        let doc = JsonConverter().convertToJSONFrom(string: inputString)

        if let a = doc["a"] as? String {
            vc.leftTextView.string = a
        }

        if let b = doc["b"] as? String {
            vc.rightTextView.string = b
        }

    } else {
        throw NSError(domain: NSOSStatusErrorDomain, code: unimpErr, userInfo: nil)
    }
}

主界面

我不知道第二個(右側)的來源。

編輯:我剛剛注意到,如果我雙擊一個保存的文件,我會得到這個錯誤,奇怪的是,不會從read()函數中的任何NSErrors中觸發。

首先,從菜單中打開是我上面所指的。

編輯2:更正。 “有時”它會打開兩個窗口。 但是即使這樣做,兩者都是空的。 我沒有得到的是,這個讀取功能是如此簡單,沒有太多出錯。 感覺一切都在引擎蓋下橫擺。

雙擊文件時出錯。

我不知道第二個(右側)的來源。

看起來好像是您的read()函數調用了makeWindowControllers() 文檔中

該方法由NSDocumentController open ...方法調用,但是您可能希望在某些情況下直接調用它。

當打開一個文檔時,它當然也會被讀取,因此makeWindowControllers()被調用兩次:一次是通過文檔的內置打開行為,一次是通過read()覆蓋。

更正。 “有時”它會打開兩個窗口。 但是即使這樣做,兩者都是空的。

也許您偶爾遇到一個錯誤,該錯誤會阻止文檔甚至進入read()調用。

如果我雙擊保存的文件,則會出現此錯誤

這支持在您甚至要read()之前出事的想法。 您可以通過將日志消息放入read()並在僅打開一個窗口的情況下在控制台中檢查該消息來輕松找到。 另外,您的應用程序委托中是否覆蓋了任何application(open...)方法? 可能其中之一是導致錯誤的原因。

更新:

在處理了一個簡單的基於文檔的項目后,我發現NSDocument確實確實為您調用了makeWindowControllers() ,但是調用read() 之后才這樣做。 read()方法中的斷點將顯示沒有視圖控制器,因為尚未調用makeWindowControllers() 這是我的read()方法:

override func read(from data: Data, ofType typeName: String) throws {
    // makeWindowControllers();
    guard let text = String(bytes: data, encoding: .utf8) else { return }
    self.content = text
}

如果我取消對makeWindowControllers()的調用的注釋, makeWindowControllers()出現與您詢問的症狀相同的信息:兩個窗口打開,只有其中一個窗口顯示內容。 但是,如果我創建一個新文檔,則只會得到一個窗口,因為從不調用read()方法。

因此,此應用在這一點上非常基礎。 視圖控制器有兩個出口,並在NSTextViewDelegate的textDidChange函數中設置文本。 就是這樣。 默認為應用程序委托,然后為Document類。 如果我不調用makeWindowControllers,則windowControllers為空。 如果我叫它,那么我有1個控制器,這就是我用來更新UI的控制器。 不太確定如何解決。

您正在嘗試在read()方法中做太多事情。 NSDocument非常面向MVC,您可以將文檔視為一種控制器-將視圖和數據聯系在一起。 read()方法旨在讓您讀取數據,並且在此之后才創建視圖。 我認為這可能是因為數據可能確定要創建哪種視圖。 我的文檔類具有僅是字符串的content屬性,而read()只是從文件中獲取數據並將其粘貼在字符串中。 在我的情況下, makeWindowControllers()會自動為我調用,而我的覆蓋使用content來設置窗口:

override func makeWindowControllers() {
    // Returns the Storyboard that contains your Document window.
    let storyboard = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
    let windowController = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("Document Window Controller")) as! WindowController
    windowController.text = self.content
    self.addWindowController(windowController)
}

另外,如果我注釋掉對makeWindowControllers的調用,則在打開文件時永遠不會調用它。 記錄證明,手動調用僅調用一次,不手動調用則調用零次。

如果您的log語句在makeWindowControllers() ,則對此沒有很好的解釋。 它與我所看到的不一致,所以請您a)檢查您的工作,b)在評論或您的問題中在此處添加更多信息。 再次,我看到makeWindowControllers()被調用而無需顯式調用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM