【问题标题】:Swift making copies of passed class instancesSwift 复制传递的类实例
【发布时间】:2017-07-26 00:40:42
【问题描述】:

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

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

类似:

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


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

对于应该是相对简单的解决方案,我没有取得太大的成功。我对 Swift 和 iOS 开发太陌生了。

【问题讨论】:

  • 这两个方法在什么类?使用使用这些方法演示问题的示例代码更新您的问题。阐明代码实际发生的情况以及您希望发生的情况。
  • 我不明白为什么这很难理解。我想弄清楚如何制作传递给 init 的项目的副本,以便我可以将它存储到两个不同的地方,这样它们就不会共享相同的引用。这将让我对其中一个进行更改,如果用户决定撤消这些更改,我可以调用重置函数来执行此操作。
  • 确保Item 有一个复制初始化器,并使用它。请注意,如果您不进行深拷贝,如果任何属性是引用类型,您可能仍然会遇到问题,因为如果您进行浅拷贝,您将拥有两个不同的 Item 对象,但它们都会引用到它们的引用类型成员变量的相同实例。

标签: swift swift3 pass-by-reference


【解决方案1】:

使用 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.value1item2.value20。 以下行创建 item1 的副本并将其分配给 item2:

var item2 = item1

从此行对item2 的任何更改都不会反映在item1 中。

结论

您的问题可以通过将Item 定义为struct 来解决

【讨论】:

    【解决方案2】:

    在操场上(在朋友的帮助下)写了以下内容:

    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))
    

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

    这完全符合我在代码中的需要

    【讨论】:

    • 我知道这个例子已经有 3 年历史了,但是它在 swift 5.1 中崩溃了:[<Test 0x600002d66760> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key a。您需要将@objc dynamic 放在属性前面才能修复它。
    猜你喜欢
    • 1970-01-01
    • 2019-10-23
    • 2021-11-21
    • 1970-01-01
    • 2014-08-24
    • 2014-08-12
    • 1970-01-01
    • 2023-03-18
    • 2012-06-28
    相关资源
    最近更新 更多