Я не понимаю, откуда идет второй (справа).
Похоже, что это происходит от вашей read()
функции, которая вызывает makeWindowControllers()
. Из документации :
Этот метод вызывается методами open ... NSDocumentController, но в некоторых случаях вы можете вызывать его напрямую.
Когда документ открыт, он, конечно, также читается, поэтому 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()
, у меня появится тот же симптом, о котором вы спрашиваете: открываются два окна, и только одно из них показывает содержимое. Однако, если я создаю новый документ, я получаю только одно окно, потому что метод read()
никогда не вызывается.
Так что на данный момент это базовое приложение. Контроллер представления имеет пару выходов и устанавливает текст в функции textDidChange NSTextViewDelegate. Но это все. App делегат по умолчанию, затем класс Document. Если я не вызываю makeWindowControllers, то windowControllers пуст. Если я это называю, то у меня есть 1 контроллер, который я использую для обновления пользовательского интерфейса. Не совсем уверен, как обойти это.
Вы пытаетесь сделать слишком много в вашем 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, он никогда не будет вызываться при открытии файла. Регистрация доказывает, что он вызывается только один раз с ручным вызовом и ноль без него.
У меня нет хорошего объяснения этому, если ваш лог-оператор находится в makeWindowControllers()
. Это не согласуется с тем, что я вижу, поэтому я бы попросил вас: а) проверить вашу работу и б) добавить больше информации здесь, либо в комментарии, либо в вашем вопросе. Опять же, я вижу, что makeWindowControllers()
вызывают без необходимости явного вызова.