打开基于 NSDocument 的应用会加载两个 windows
Opening NSDocument based app loads two windows
我有一个简单的基于 NSDocument 的应用程序,它有两个文本字段(假设 git 不同)。当我打开我的文件时,它会打开两个 windows 和我的文件名。第一个 window 一切正常。第二个 UI 是空的,文件名相同。
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: 更正。 'Sometimes' 它打开两个 windows。但即使这样做,两者都是空的。我不明白的是这个读取函数非常简单,不会出错。感觉这一切都在幕后进行。
I don't get where the second one (on the right) is coming from.
看起来它可能来自您的 read()
函数,该函数调用 makeWindowControllers()
。来自 the documentation:
This method is called by the NSDocumentController open... methods, but you might want to call it directly in some circumstances.
打开文档时,当然也会读取它,因此 makeWindowControllers()
被调用两次:一次是文档的内置打开行为,一次是您的 read()
覆盖。
Correction. 'Sometimes' it opens two windows. But even when it does that, both are empty.
也许您遇到了一个偶发错误,导致文档无法进入 read()
调用。
if I double click a saved file, I get this error
这支持了在您到达 read()
之前就出现问题的想法。您可以通过在 read()
中放置一条日志消息并在只有一个 window 打开的情况下检查该消息的控制台来很容易地找到。另外,您的应用程序委托中是否覆盖了任何 application(open...)
方法?也许其中之一是造成错误的原因。
更新:
在对一个简单的基于文档的项目进行了一番研究之后,我发现 NSDocument
确实会为您调用 makeWindowControllers()
,但它会在 after[=64] 之后调用=] 它调用 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()
的调用,我会得到与您询问的相同的症状:两个 windows 打开,并且只有其中一个显示内容。但是,如果我创建一个新文档,我只会得到一个 window,因为 read()
方法永远不会被调用。
So this app is very basic at this point. View controller has a couple outlets and sets the text in NSTextViewDelegate's textDidChange function. But that's it. App delegate default, then the Document class. If I don't call makeWindowControllers then windowControllers is empty. If I call it, then I have 1 controller, which is what I use to update the UI. Not really sure how to get around that.
您试图在 read()
方法中做太多事情。 NSDocument
非常面向 MVC,您可以将文档视为一种控制器——它将视图和数据联系在一起。 read()
方法旨在让您读取数据,并且在此之后才会创建视图。我认为这可能是因为数据可能决定要创建哪种视图。我的文档 class 有一个 content
属性 只是一个字符串,而 read()
只是从文件中获取数据并将其粘贴到字符串中。在我的例子中,makeWindowControllers()
会自动为我调用,我的覆盖使用 content
来设置 window:
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)
}
Also, if I comment out the call to makeWindowControllers, it never gets called when I open a file. Logging proves that its only called once with the manual call and zero times without it.
如果你的日志语句在 makeWindowControllers()
中,我对此没有很好的解释。这与我所看到的不一致,所以我会要求您 a) 检查您的工作并 b) 在此处添加更多信息,无论是在评论中还是在您的问题中。同样,我看到 makeWindowControllers()
被调用而无需显式调用它。
我有一个简单的基于 NSDocument 的应用程序,它有两个文本字段(假设 git 不同)。当我打开我的文件时,它会打开两个 windows 和我的文件名。第一个 window 一切正常。第二个 UI 是空的,文件名相同。
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: 更正。 'Sometimes' 它打开两个 windows。但即使这样做,两者都是空的。我不明白的是这个读取函数非常简单,不会出错。感觉这一切都在幕后进行。
I don't get where the second one (on the right) is coming from.
看起来它可能来自您的 read()
函数,该函数调用 makeWindowControllers()
。来自 the documentation:
This method is called by the NSDocumentController open... methods, but you might want to call it directly in some circumstances.
打开文档时,当然也会读取它,因此 makeWindowControllers()
被调用两次:一次是文档的内置打开行为,一次是您的 read()
覆盖。
Correction. 'Sometimes' it opens two windows. But even when it does that, both are empty.
也许您遇到了一个偶发错误,导致文档无法进入 read()
调用。
if I double click a saved file, I get this error
这支持了在您到达 read()
之前就出现问题的想法。您可以通过在 read()
中放置一条日志消息并在只有一个 window 打开的情况下检查该消息的控制台来很容易地找到。另外,您的应用程序委托中是否覆盖了任何 application(open...)
方法?也许其中之一是造成错误的原因。
更新:
在对一个简单的基于文档的项目进行了一番研究之后,我发现 NSDocument
确实会为您调用 makeWindowControllers()
,但它会在 after[=64] 之后调用=] 它调用 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()
的调用,我会得到与您询问的相同的症状:两个 windows 打开,并且只有其中一个显示内容。但是,如果我创建一个新文档,我只会得到一个 window,因为 read()
方法永远不会被调用。
So this app is very basic at this point. View controller has a couple outlets and sets the text in NSTextViewDelegate's textDidChange function. But that's it. App delegate default, then the Document class. If I don't call makeWindowControllers then windowControllers is empty. If I call it, then I have 1 controller, which is what I use to update the UI. Not really sure how to get around that.
您试图在 read()
方法中做太多事情。 NSDocument
非常面向 MVC,您可以将文档视为一种控制器——它将视图和数据联系在一起。 read()
方法旨在让您读取数据,并且在此之后才会创建视图。我认为这可能是因为数据可能决定要创建哪种视图。我的文档 class 有一个 content
属性 只是一个字符串,而 read()
只是从文件中获取数据并将其粘贴到字符串中。在我的例子中,makeWindowControllers()
会自动为我调用,我的覆盖使用 content
来设置 window:
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)
}
Also, if I comment out the call to makeWindowControllers, it never gets called when I open a file. Logging proves that its only called once with the manual call and zero times without it.
如果你的日志语句在 makeWindowControllers()
中,我对此没有很好的解释。这与我所看到的不一致,所以我会要求您 a) 检查您的工作并 b) 在此处添加更多信息,无论是在评论中还是在您的问题中。同样,我看到 makeWindowControllers()
被调用而无需显式调用它。