2016-02-05 34 views
0

在这里,似乎有很多困惑和不同的意见,我想知道,迅速做出对象的浅拷贝而不是深拷贝是可能的。在swift中创建集合类(Array,Dictionary)的浅表副本,而不是深层副本。

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

我试过initWithArray:copyItems:检查当我更改copyItems的布尔标志时,它会产生什么差别,但是我看不到任何区别。我应该通过更改copyItems标志来区分浅拷贝或深拷贝,但是我错了,它总是创建一个深层拷贝。

请检查我的下面的代码,我使用initWithArray将copyObject对象arrayObject1复制到arrayObject2:copyItems:通过将copyItems:设置为true。我将arrayObject2的第0个字符串对象更改为新的字符串对象,并将arrayObject2的第0个对象更改,但是arrayObject1第0个对象未更改。而如果我通过将copyItems:赋值为false来复制它,那么我也得到了相同的结果。

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

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

回答

1

这是因为name是Swift String实例。字符串是结构体,因此它是一个值类型。那是因为它总是被价值复制。 arrayObject1 as [AnyObject]是一个转换为swift数组(也是一个结构体),其中包含String对象。

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

我只能拿出拳击结构实例的想法变成一个类包装:

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 
+0

嗨,欣赏你的答案是事实。但如果你能帮助我,我还有其他问题。我改变了copyItems:标志为真,这是由**崩溃'NSArrayThoroughConcept.StringBox'没有实现methodSignatureForSelector: - 麻烦未来 - 无法识别的选择器 - [NSArrayThoroughConcept.StringBox copyWithZone:] **我可以知道它是什么让变化改变国旗true/false – KiranJasvanee

+1

@Kiran我编辑了我的答案。您应该采用'NSCopying'并实施'copyWithZone:'方法以支持深度复制。标志'copyItems'确定数组项是否通过引用被复制(然后通过复制对象指针与适当的ARC工作来复制)或通过值(然后您应该提供复制类的项目的方法)。 – slashdot

+0

其实这就是我想知道的,并学习如何通过**数组帮助实现浅层和深层复制:copyItems ** – KiranJasvanee

1

arrayObject2[0] = "john"

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

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

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

如果你问它,副本很浅。从技术上讲,浅层和深层复制有时是数据类型的同一事物是不可变的。

+0

我明白你的回答,能否请您解释与一些代码通过使用NSMutableString这不是不可改变的 – KiranJasvanee

相关问题