swift - 复制命令 - 深复制还是浅复制?

标签 swift swift3 copy

当我在 iOS (swift/Objective c) 中使用复制命令复制对象时,这是浅复制还是深复制?

var str = "Hello, playground"
var copyStr = str.copy()

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

帮我看看上面几行,这是深拷贝还是浅拷贝?

The issue is , this behaviour in objective c is showing me the same address with both string and array which is shallow copy and in swift3 it is showing me different address which is deep copy

最佳答案

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

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 以外的对象,因为这些对象的优化可能会使查看地址产生误导。

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

original address: 0x618000044920
    0x6180000277e0
    0x618000027f00
    0x618000027ea0
copy address: 0x618000044920
    0x6180000277e0
    0x618000027f00
    0x618000027ea0

事实上,正如您所看到的,因为它是一个不可变的 NSArray,所以它似乎在副本实际上返回相同数组实例的情况下对此进行了优化。如果您使用可变数组 NSMutableArray,您将看到返回的两个唯一数组,如您所料,但它们仍然指向同一个对象集合。

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

let copyArray = NSArray(array: originalArray as! [Any], copyItems: true)

这会产生一个深层复制(两个唯一的数组,其中复制各个成员对象,并且它们也具有唯一的地址):

original address: 0x618000059e60
    0x618000027ae0
    0x618000028340
    0x618000028280
copy address: 0x61800005ba20
    0x618000028800
    0x618000028aa0
    0x618000028400

参见the documentation对于 init(array:copyItems:) 来说:

The copy(with:​) method performs a shallow copy. If you have a collection of arbitrary depth, passing true for the flag parameter [of init(array:copyItems:)] will perform an immutable copy of the first level below the surface. If you pass false the mutability of the first level is unaffected. In either case, the mutability of all deeper levels is unaffected.


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

关于swift - 复制命令 - 深复制还是浅复制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43145351/

相关文章:

iOS 摇一摇手势 - 双摇

php - 与网站、Swift + PHP 相比,应用程序中 mysql 查询的结果不同

swift - 如果按钮宽度大于按钮图像的宽度(xcode),则将按钮图像保持在左侧位置

error-handling - 如何使用 RecoverableError 重试?

ios - 无法将类型 'String?' 的值转换为预期的参数类型 'URL'

java - 使用ant将子文件夹复制到目录

ios - Swift NSNotificationCenter 不会触发

ios - 错误 : Value of type string has no member componentsSeparatedByCharactersInSet

c++ 隐式复制构造函数是否复制数组成员变量?

Linux : Copy Multiple files and remove it's extension