값이 참조 유형 일 때 NSUndoManager가 값을 캡처하는 방법을 이해하는 데 문제가 있습니다. undoManager를 사용하려고 할 때마다 값은 실행 취소되지 않습니다.NSUndoManager : 참조 유형 캡처 가능?
참고 : 나는 맥 OS 10.10 지원해야, 난, -1로 그들 모두를 다시 나는 ID 번호의 상태를 저장 스위프트 3, 엑스 코드 (8) 여기
를 사용하여 다음 취소하려고하고 있습니다. 결과는 모두 여전히 -1입니다.
import Cocoa
class Person: NSObject {
var id: ID
init(withIDNumber idNumber: Int) {
self.id = ID(idNumber)
}
}
class ID: NSObject {
var number: Int
init(_ number: Int) {
self.number = number
}
}
ViewController... {
@IBAction func setIDsToNegative1(_ sender: NSButton) {
var savedIDs: [ID] = []
for person in people {
savedIDs.append(person.id)
}
undoManager?.registerUndo(withTarget: self, selector:#selector(undo(savedIDs:)), object: savedIDs)
for person in people {
person.id.number = -1
}
}
func undo(savedIDs: [ID]) {
for id in savedIDs {
print(id.number)
}
//Prints -1, -1, -1
}
}
ID 개체를 저장하는 대신 값을 캡처하는 것이 문제라는 것을 증명하기 위해 포함 된 Int 값을 저장했습니다. Ints가 값 유형이므로 완벽하게 작동했습니다.
그런 다음 클로저 캡처에 대해 좀 더 읽고이를 시도했습니다.
undoManager?.registerUndo(withTarget: self, handler: { [saved = savedIDs]
(self) ->() in
self.undo(savedIDs: saved)
})
같은 문제는 모두 여전히 -1입니다.
덕분에, 이것은 내가 "동결 건조"참조 상태가 불가능하다고하지만 의심 것을 확인 . 제공된 예제에서는 데이터 구조가 매우 간단하여 튜플을 절약하는 것이 쉽습니다. 하지만 다른 참조 유형으로 구성된 훨씬 복잡한 데이터 구조를 가진 클래스를 실행 취소하려면 어떻게해야합니까? 객체 구조를 자세히 조사하고 모든 값 유형을 추출해야합니다. 그렇지 않습니까? 나는 그것이 여기에 제안했던 것과 같은 것을하는 것이 훨씬 쉽다고 생각한다 : http://stackoverflow.com/questions/24326984/how-do-i-register-nsundomanager-in-swift/41619219#41619219 – MH175
당신은 그렇게 할 수있다. 저는 여러분이 모든 단일 객체의 실행 취소 상태를 관리해야하는 상처를 겪고 있다고 생각합니다. 특히 객체 계층 구조에서 작업 할 때 특히 그렇습니다. 모든 속성에 대해 실행 취소 스택이 필요하다는 것을 명심하십시오. 게다가 모든 단일 ID 객체에서 undo()를 호출해야하므로이 경우에도 도움이되지 않습니다. 모델에 가능한 한 값 유형을 사용하는 것을 고려하십시오 - 값 유형은 예상대로 값을 캡처합니다. – MrMage