У меня возникли проблемы с внедрением более сложного подхода к отмене регистрации в Swift, основанного на вызовах (на основе статьи NSHipster здесь Документы Apple по-прежнему содержат весь пример кода на Objective-C, и семантика для настройки вызова сильно отличается).
Мой NSDocument
подкласс Document
имеет следующий метод, который работает с объектами модели, которые я хочу сделать невыполнимыми:
func rename(object: Any, to newName: String) {
// This is basically a protocol that requires implementing:
// var name: String { get set }
//
guard var namedObject = object as? EditorHierarchyDisplayable else {
return
}
// Register undo:
let undoController = undoManager?.prepare(withInvocationTarget: self) as? Document
undoController?.rename(object: namedObject, to: namedObject.name)
undoManager?.setActionName("Rename \(namedObject.localizedClassName)")
// Perform the change:
namedObject.name = newName
}
Я обнаружил, что undoController
выше равно nil
, потому что попытка приведения к Document
не удалась. Если я удалю приведение (и закомментирую вызов undoController.rename(...
), prepare(withInvocationTarget:)
вернет следующий объект:
(lldb) print undoController
(Any?) $R0 = some {
payload_data_0 = 0x00006080000398a0
payload_data_1 = 0x0000000000000000
payload_data_2 = 0x0000000000000000
instance_type = 0x000060800024f0d8
}
(lldb) print undoController.debugDescription
(String) $R1 = "Optional(NSUndoManagerProxy)"
(lldb)
Что я упустил?
prepare(withInvocationTarget:)
говорит, что возвращает self.self
этоundoManager
. В нижней части статьи NSHipster написано, что в этой статье используется Swift версии 1.0. - person Willeke   schedule 21.08.2017as ViewController
(я предполагаю, что в моем случае это становитсяDocument
). Кроме того,as
становитсяas?
в Swift 2+. - person Nicolas Miari   schedule 21.08.2017NSUndoManager
вDocument
неверно. Swift 1 было все равно, но Swift 3 отказывается это делать. - person Willeke   schedule 21.08.2017Document
методrename(object:to:)
на возвращенном прокси? Objective-C позволяет отправлять любое сообщение любому объекту (по крайней мере, во время компиляции), но Swift строго типизирован... - person Nicolas Miari   schedule 21.08.2017let undoController : ViewController = undoManager?.prepareWithInvocationTarget(self) as ViewController
. Как это перевести на Swift 3? - person Nicolas Miari   schedule 21.08.2017registerUndoWithTarget<TargetType>(target: TargetType, handler: TargetType -> ())
. Спасибо. - person Nicolas Miari   schedule 21.08.2017