首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >复制命令-深拷贝还是浅拷贝?

复制命令-深拷贝还是浅拷贝?
EN

Stack Overflow用户
提问于 2017-03-31 16:18:22
回答 2查看 884关注 0票数 2

当我用iOS中的copy命令复制对象时,是浅层拷贝还是深拷贝?

代码语言:javascript
运行
复制
var str = "Hello, playground"
var copyStr = str.copy()

代码语言:javascript
运行
复制
var originalArray = [1, 2, 3, 4] as NSArray
var copyArray = originalArray.copy()

withUnsafePointer(to: &originalArray) {
    print(" originall address: \($0)")
}

withUnsafePointer(to: &copyArray) {
    print(" copy address: \($0)")
}

帮我看上面的台词,这是深版还是浅版?

问题是,目标c中的这种行为是向我显示相同的地址,其中字符串和数组都是浅拷贝,而在swift3中,则显示了不同的地址,即深度复制。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-31 17:11:28

copy执行浅拷贝(集合的副本,但数组中的对象未被复制)。例如。

代码语言:javascript
运行
复制
let obj1 = Object(value: 1)
let obj2 = Object(value: 2)
let obj3 = Object(value: 3)

let originalArray = [obj1, obj2, obj3] as NSArray
let copyArray = originalArray.copy() as! NSArray

print(String(format: "original address: %p", originalArray))

for obj in originalArray {
    print(String(format: "    %p", obj as! Object))
}

print(String(format: "copy address: %p", copyArray))

for obj in copyArray {
    print(String(format: "    %p", obj as! Object))
}

注意,我使用的对象不是NSNumberNSString,因为这些对象具有可能使查看地址具有误导性的优化。

这两个数组的成员对象指向相同的对象(即浅拷贝)。

代码语言:javascript
运行
复制
original address: 0x618000044920
    0x6180000277e0
    0x618000027f00
    0x618000027ea0
copy address: 0x618000044920
    0x6180000277e0
    0x618000027f00
    0x618000027ea0

事实上,正如您所看到的,因为它是一个不可变的NSArray,所以它似乎优化了它,其中副本实际上是返回相同的数组实例。如果您使用可变数组NSMutableArray,您将看到两个返回的唯一数组,正如您所期望的那样,但是它们仍然指向相同的对象集合。

但是,如果将NSArray(array:copyItems:)true一起用于copyItems,则将得到两个具有每个成员对象的唯一副本的唯一数组:

代码语言:javascript
运行
复制
let copyArray = NSArray(array: originalArray as! [Any], copyItems: true)

这将产生一个深拷贝(两个唯一的数组,其中每个成员对象都被复制,并且它们也有唯一的地址):

代码语言:javascript
运行
复制
original address: 0x618000059e60
    0x618000027ae0
    0x618000028340
    0x618000028280
copy address: 0x61800005ba20
    0x618000028800
    0x618000028aa0
    0x618000028400

关于文献资料,请参阅init(array:copyItems:),它说:

copy(with:​)方法执行浅拷贝。如果您有一个任意深度的集合,将true传递给init(array:copyItems:)flag参数将执行表面以下第一级的不可变副本。如果通过false,第一级的可更改性将不受影响。在这两种情况下,所有更深层次的变化都不受影响。

不过,就个人而言,如果编写Swift,我通常会使用ArrayDictionary值类型,而不是旧的NSArrayNSDictionary类型。

票数 3
EN

Stack Overflow用户

发布于 2017-03-31 16:39:09

Swift中的字符串是值类型。对于所有值类型,将创建现有字符串值的新副本。

来自苹果公司的文件。

Swift的默认复制字符串行为确保了当一个函数或方法传递一个字符串值时,您显然拥有确切的字符串值,而不管它来自何处。除非您自己修改,否则您可以确信所传递的字符串不会被修改。

希望这能有所帮助

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43145351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档