2016-12-19 6 views
3

스위프트 코드에서 NSUndoManagerProxy 충돌을 주조 NSUndoManager :우리는 다음과 같은 코드를 사용하고 우리의 응용 프로그램에서

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

이 경고없이 컴파일 및 맥 OS 10.12 시에라에서 잘 실행됩니다. 그러나 그것은 10.9 - 10.11 (엘 캐피 탄까지 매버릭스)에서 런타임에 충돌합니다. 충돌보고 사항 :

은 'MyObjectType'(0x108b82218)에 유형 'NSUndoManagerProxy'(0x7fff76d6d9e8)의 값을 캐스팅 할 수 없습니다. 그럼 충돌하지 않는

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

,하지만 취소는 전혀 작동하지 않습니다 :

는 그럼 난에 코드를 다시 썼다. 이 마지막 작성 방법은 Apples documentation에서 직접 나오므로 Swift 3 또는 10.12 SDK에서 동작이 변경된 것 같습니다. Swift 3 및 SDK 10.12와 함께 Xcode 8.2를 사용하고 있습니다.

registerUndo (withTarget, selector :, object :)는 더 많은 인수를 가진 실행 취소 가능 메소드가 많기 때문에 적합하지 않습니다. 실제로 그 단어들을 사전에 감싸고 싶지는 않습니다. 그리고 셀렉터가 오늘날 꽤 형식 안전하다고하더라도, 나는 여전히 그들을 좋아하지 않는다. 또한 블록 기반 API (registerUndo (withTarget : handler :))가 있지만 불행히도 10.11+에만 해당합니다.

누구든지 동일한 문제가 발생 했습니까? 그리고 더 중요한 것은 누구나 탈출구를 찾았습니까?

답변

2

첫 번째 코드가 이고 컴퓨터가 인 MacOS 10.12가 너무 많이 들었습니다. 방법 prepare(withInvocationTarget:)입니다. 거의 작동하지 않는 Swift 것입니다. 반환 된 프록시 객체는 원래 클래스의 인스턴스가 아니며 객체가 NSObject (일부 이전 OS X에서는 임대되지 않음)의 하위 객체가 아닙니다.

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

나는 또한 AnyObject에 캐스팅하는 :-)를 컴파일합니다 놀라게 해요 :

어쨌든,이 노력의 가치가 한 가지입니다. AnyObject에서 호출 된 알 수없는 메서드에 대한 컴파일러 경고가 필요합니까? 하지만 당신의 솔루션이 작동하는지 확인할 수 있습니다! – Marius

+0

나는이 솔루션이 나에게도 효과가 있다는 것을 확신 할 수있다. (왜 처음에는 에러가 발생하는지 의아할 지 모르지만) 또한 NSObject로 선언 할 필요가 있다고 덧붙이고 싶다. 'class MyObjectType {...} '을 선언하면 컴파일 오류가 발생합니다.'AnyObject '유형의 값에는'myMethod '멤버가 없습니다. " – HuaTham