在swift中创建集合类(Array,Dictionary)的浅表副本,而不是深层副本。

时间:2016-02-05 11:05:45

标签: ios arrays swift deep-copy shallow-copy

在那里似乎存在很多混淆和不同意见,我想知道,是否可以快速制作对象的浅层副本而不是深层副本。

我检查了JAVA - http://www.jusfortechies.com/java/core-java/deepcopy_and_shallowcopy.php,它清楚地解释了浅拷贝和深拷贝之间的区别,但是我没有在swift中得到一些例子。

我尝试了initWithArray:copyItems:检查当我改变copyItems的布尔标志时它有什么不同,但我看到的没有区别。我应该通过更改copyItems标志来区分浅或深拷贝,但我错了它总是创建一个深拷贝。

请检查我的下面代码,我使用initWithArray将数组对象arrayObject1克隆到arrayObject2:copyItems:将copyItems:设置为true。我将arrayObject2第0个字符串对象更改为新的字符串对象,并且更改了arrayObject2第0个对象,但是arrayObject1第0个对象没有更改。而如果我通过将copyItems:分配给false来复制它,那么我也会得到相同的结果。

那么如何实现浅拷贝,如果不是通过initWithArray:copyItems:那么copyItems:flag会对结果产生影响。

func createAnArrayUsingArrayCopyItems(){

        let name = "albort"
        let arrayObject1 = NSArray.init(objects: name, 15)
        let arrayObject2 = NSMutableArray.init(array: arrayObject1 as [AnyObject], copyItems: true)
        arrayObject2[0] = "john"
        print(arrayObject1)
        print(arrayObject2)

    }  

输出 - >
enter image description here

2 个答案:

答案 0 :(得分:1)

  

arrayObject2[0] = "john"

这是更改数组2中位置0处的项目 - 而不是已存在于该阵列位置的字符串的内容。要做到这一点,它需要是一个可变字符串数组。

实际上,如果您使用可变字符串创建数组,然后追加到数组2中位置0处的字符串,您将看到数组1中的相同字符串实例也会更新(因为它是相同的实例)。

编辑数组实例与编辑数组中的实例不同。

如果您要求,副本很浅。从技术上讲,浅层和深层副本有时与数据类型相同是不可变的。

答案 1 :(得分:1)

这是因为name是一个Swift String实例。 String是struct,因此它是一个值类型。那是因为它总是按值复制。 arrayObject1 as [AnyObject]是转换为swift Array(也是一个struct),其中包含String对象。

因此,在Swift中使用像Array和String这样的结构获取浅拷贝并不是一件容易的事。

我只能提出将struct struct实例装入类包装器的想法:

class StringBox : CustomStringConvertible, NSCopying {
  var string: String

  init(str: String) {
    string = str
  }

  var description: String {
    return "\(string)"
  }

  @objc func copyWithZone(zone: NSZone) -> AnyObject {
    return StringBox(str: string)
  }
}

func createAnArrayUsingArrayCopyItems(){
  let name = StringBox(str: "albort")
  let arrayObject1 = NSArray.init(objects: name, 15)
  let arrayObject2 = NSMutableArray.init(array: arrayObject1 as [AnyObject], copyItems: false)
  (arrayObject2[0] as! StringBox).string = "john"
  print(arrayObject1[0])
  print(arrayObject2[0])
}

createAnArrayUsingArrayCopyItems()

它给出了以下输出:

john
john