Swift制作传递的类实例的副本

Swift制作传递的类实例的副本,swift,swift3,pass-by-reference,Swift,Swift3,Pass By Reference,我有一个接受类实例的init(我希望每个人都知道这意味着它是通过引用传递的) 我希望能够复制对象并将其存储在两个类实例变量中,这样,我就有了一个函数,该函数将充当“重置”,它将设置我在某一点上所做的任何更改,并返回到以前的状态 比如: convenience init(_ item:Item?){ self.init() self.item = item self.undoItem = item } func reset(){ self.item = self

我有一个接受类实例的init(我希望每个人都知道这意味着它是通过引用传递的)

我希望能够复制对象并将其存储在两个类实例变量中,这样,我就有了一个函数,该函数将充当“重置”,它将设置我在某一点上所做的任何更改,并返回到以前的状态

比如:

convenience init(_ item:Item?){
    self.init()
    self.item = item
    self.undoItem = item
}


func reset(){
    self.item = self.undoItem
    self.reloadInfo()
}

我还没有在应该是一个相对直接的解决方案方面取得多大成功。我对Swift和iOS开发太陌生了。

使用Swift结构可能是您的一个选择

struct Item {
    //
}
Swift中的结构是值类型,它们是通过值而不是引用复制的

示例

struct Item {
    var value: Int = 1
}

var item1 = Item()
var item2 = item1
item2.value = 20

print("\(item1.value)") // 1
print("\(item2.value)") // 20
在上面的示例中,
item1.value
1
item2.value
20
。 以下行创建item1的副本并将其分配给item2:

var item2 = item1
从此行开始,对
item2
的任何更改都不会反映在
item1

结论

struct Item {
    var value: Int = 1
}

var item1 = Item()
var item2 = item1
item2.value = 20

print("\(item1.value)") // 1
print("\(item2.value)") // 20
您的问题可以通过将
项定义为
结构来解决(在朋友的帮助下)在操场上写了以下内容:

protocol Copyable {
   func copyOfValues() -> AnyObject
}

extension Copyable where Self: NSObject {
    func copyOfValues() -> AnyObject{
        var copyOfOriginal = Self()
        let mirror = Mirror(reflecting: self)
        for (label, value) in mirror.children {
            if let label = label {
                copyOfOriginal.setValue(value, forKey: label)
            }
       }

        return copyOfOriginal
    }
}

class Test: NSObject, Copyable {
    var a = 1
    var b = 2
}

var test = Test()
var copy = test.copyOfValues() as! Test

print(dump(test))
print(dump(copy))
copy.a = 10
print(dump(test))
print(dump(copy))
这是一个很好且简单的函数,因此我可以在swift中获取类实例的副本。在swift中,由于它们是一种引用类型(我不确定是否可以取消引用它或诸如此类),所以基本上每次都必须为对象编写一个自定义复制函数。好的,现在我写了这个,所以只要您使用NSObject的子类并使用这个协议,您就可以了


这正是我在代码中所需要的

这两个方法在哪个类中?使用示例代码更新您的问题,该示例代码使用这些方法演示问题。澄清代码实际发生了什么以及您希望发生什么。我不明白为什么这很难理解。我想弄清楚如何能够创建传递到init的项的副本,以便将其存储到两个不同的位置,这样它们就不会共享相同的引用。这将允许我对其中一项进行更改,如果用户决定撤消这些更改,我可以调用重置函数来执行此操作。请确保
具有副本初始值设定项,并使用它。请注意,如果不进行深度复制,如果任何属性都是引用类型,则可能仍然存在问题,因为如果进行浅层复制,将有两个不同的
对象,但是它们都引用了它们引用类型成员变量的相同实例。复制可能的重复我知道这个例子已经3年了,但它在swift 5.1中崩溃:
[setValue:forUndefinedKey:]:这个类不符合密钥a的键值编码。您需要在属性前面放置
@objc dynamic
来修复它。