NSPersistentDocument, Swift, macOS и раскадровки — как получить manageObjectContext?

Прошло много времени с тех пор, как я занимался CoreData и macOS, еще во времена xib и nibs. С xib есть «Владелец файла», который может предоставить вам доступ к вашему документу и управляемому ObjectContext. Легкий.

С NSPersistentDocument и моей раскадровкой у меня возникла небольшая проблема с курицей и яйцом. В моем классе Document, подклассе NSPersistentDocument, у меня есть следующее:

override func makeWindowControllers() {
    // Returns the Storyboard that contains your Document window.
    let storyboard = NSStoryboard(name: "Main", bundle: nil)
    let windowController = storyboard.instantiateControllerWithIdentifier("Document Window Controller") as! NSWindowController // <- when I need the moc
    self.addWindowController(windowController)
    windowController.contentViewController!.representedObject = self // <- when I set the representedObject
}

Кажется, это то, что предлагают многие люди, включая Apple.

Моя проблема заключается в следующем: в MainViewController я хочу иметь Object Controller, и он должен быть привязан к manageObjectContext, но когда ему нужно иметь manageObjectContext, я еще не установил для представленного объекта значение self. Поэтому выбрасывается исключение. Задавать представляемый объект в конце метода makeWindowControllers слишком поздно, но я все равно не вижу возможности сделать это раньше.


person AutomatonTec    schedule 16.07.2016    source источник


Ответы (1)


Хорошо. Так. Я не знаю, что происходило прошлой ночью, но я никак не мог заставить это работать.

Сегодня утром я перечитал документацию по представленному объекту:

Представленное свойствоObject является совместимым с кодированием "ключ-значение" и соблюдением "ключ-значение". Когда вы используете представленный объект в качестве владельца файла nib-файла, вы можете привязать элементы управления к владельцу файла, используя ключевые пути, которые начинаются со строки createdObject.

Документы ясно говорят мне, что магия заключается в представленном объекте. Поэтому я убедился, что мой метод makeWindowControllers был таким, как указано выше, и я убедился, что мой объектный контроллер в моей раскадровке был таким, как указано в документах.

Не обращайте внимания на (!)

Я не был удивлен, что путь имеет немного (!), потому что представленный объект — это просто AnyObject.

Затем я покорно запустил приложение, полностью ожидая, что оно не сработает.

Но это сработало. Не знаю, почему вчера этого не произошло, но я мало что могу сделать с уже потерянными часами.

Дополнение. В качестве эксперимента я попробовал один из вчерашних поворотов. Чтобы избавиться от (!) и иметь под рукой ссылку на moc, я добавил этот метод в MainViewController:

var moc:NSManagedObjectContext? {
    if let doc = self.representedObject as? Document {
        return doc.managedObjectContext
    }
    return nil
}

А затем я использовал «self.moc» в качестве пути к ключу модели для моего объектного контроллера. Это не сработало, и было выброшено знакомое исключение. Восстановите путь ключа модели к «self.representedObject.managedObjectContext», и все будет хорошо работать. … как по волшебству.

person AutomatonTec    schedule 16.07.2016
comment
Этот метод не работает, поскольку использует статическую диспетчеризацию. Попробуйте добавить @objc dynamic перед var moc. - person Shmidt; 14.12.2018