gpt4 book ai didi

swift - NSUndoManager:可以捕获引用类型吗?

转载 作者:行者123 更新时间:2023-11-28 15:57:02 26 4
gpt4 key购买 nike

当值是引用类型时,我无法理解 NSUndoManager 如何捕获值。每当尝试使用 undoManager 时,这些值都不会撤消。

注意:我需要支持 macOS 10.10,我使用的是 Swift 3 和 XCode 8

这里我保存了ID号的状态,将它们全部重置为-1,然后尝试撤销。结果还是都是-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 值。它工作得很好,因为 Int 是值类型。

然后我阅读了更多关于闭包捕获的内容并尝试了这个。

undoManager?.registerUndo(withTarget: self, handler: { [saved = savedIDs] 
(self) -> () in
self.undo(savedIDs: saved)
})

同样的问题,仍然是-1。

最佳答案

NSUndoManager 并不是真正关于捕获旧的,而是关于捕获操作恢复原始值值(value)观。

您只捕获对 ID 的引用。所以 savedIDs 中的元素指向与 people 元素的 id 属性相同的对象,即当你改变一个时,你也换一个。

您需要做的是手动保存 ID 和您想要将它们重置为的值,如下所示:

let savedPairs = people.map { (id: $0.id, originalValue: $0.id.number) }

这确保 idnumber 值本身保存在某处,而不仅仅是指向 id 的指针。

然后您可以注册一个操作,使用您手动捕获的值执行撤消操作,如下所示:

undoManager.registerUndo(withTarget: self) {
savedPairs.forEach { $0.id.number = $0.originalValue }
}

关于swift - NSUndoManager:可以捕获引用类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41575694/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com