2016-12-19 4 views
3

В нашем приложении мы используем следующий код:NSUndoManager литье NSUndoManagerProxy аварии в Swift код

let lInvocationTarget = lUndoManager.prepare(withInvocationTarget: self) 
let _ = (lInvocationTarget as! MyObjectType).myMethod(_: self.opacity, undoManager: lUndoManager) 

компилируется без предупреждений и прекрасно работает под MacOS 10.12 Sierra. Однако он падает во время выполнения 10,9 - 10,11 (Mavericks до El Capitan). В докладе аварии уведомления:

Не удалось бросить значение типа 'NSUndoManagerProxy' (0x7fff76d6d9e8) к 'MyObjectType' (0x108b82218).

Тогда я переписал код:

if let lInvocationTarget = lUndoManager.prepare(withInvocationTarget: self) as? MyObjectType { 
    let _ = lInvocationTarget.setOpacity(_: self.opacity, undoManager: lUndoManager) 
} 

Тогда это не крах, а затем Undo не работает вообще. Этот последний способ записи происходит непосредственно из Apples documentation, поэтому, по-видимому, поведение изменилось в Swift 3 или 10.12 SDK. Я использую Xcode 8.2 с Swift 3 и SDK 10.12

RegUndo (withTarget, selector :, object :) не подходит, потому что у меня есть много других отмененных методов с большим количеством аргументов. На самом деле не хотят обертывать их в словаре orso. И даже когда селектора в настоящее время довольно безопасны, мне все равно не нравятся. Существует также основанный на блоке API (registerUndo (withTarget: handler :)), но это, к сожалению, только для 10.11+.

Кто-нибудь сталкивался с той же проблемой? И что еще важнее: кто-нибудь придумал выход?

ответ

2

Я так удивлен, что слышу ваш первый код работы на macOS 10.12. Метод prepare(withInvocationTarget:) был этой вещи с трудом в Swift. Не только возвращаемый прокси-объект не является экземпляром исходного класса, но ни один объект не является потомком NSObject (в аренду в некоторых бывших OS Xs).

Во всяком случае, это одна вещь, которую стоит попробовать:

let lInvocationTarget = lUndoManager.prepare(withInvocationTarget: self) 
_ = (lInvocationTarget as AnyObject).myMethod(self.opacity, undoManager: lUndoManager) 
+0

Я также удивлен, что кастинг на AnyObject компилирует :-). Предсказывали предупреждения компилятора для неизвестного метода, вызванного AnyObject. Но я могу подтвердить, что ваше решение работает! – Marius

+0

Я могу подтвердить, что это решение также работает для меня (хотя мне интересно, почему ошибка появляется в первую очередь), но я хотел бы добавить, что мне также нужно было объявить «MyObjectType» как «NSObject». Объявление класса 'MyObjectType {...}' приведет к ошибке компиляции "значения типа« AnyObject »не имеет члена myMethod». – HuaTham

 Смежные вопросы

  • Нет связанных вопросов^_^