当我在iOS(swift / objective c)中使用copy命令复制对象时,这是浅拷贝还是深拷贝?
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: ©Array) {
print(" copy address: \($0)")
}
请帮我看一下上面的行,这是一份深拷贝还是浅拷贝?
问题是,目标c中的这种行为向我展示了同样的情况 字符串和数组都是浅拷贝和swift3 它向我展示了不同的地址,即深拷贝
答案 0 :(得分:3)
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))
}
执行浅拷贝(集合的副本,但不复制数组中的对象)。 E.g。
NSNumber
注意,我使用NSString
和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
产生一个深层副本(两个唯一的数组,其中复制了各个成员对象,它们也有唯一的地址):
init(array:copyItems:)
请copy(with:)
查看true
,其中包含:
flag
方法执行浅拷贝。如果您有任意深度的集合,则init(array:copyItems:)
参数[{1}}]的false
传递将执行表面下第一级的不可变副本。如果您通过Array
,则第一级的可变性不受影响。在任何一种情况下,所有更深层次的可变性都不会受到影响。
就个人而言,如果编写Swift,我通常会使用Dictionary
和NSArray
值类型,而不是旧的NSDictionary
和 std::map<std::string, stockDictType::iterator, Comparator> stocksTicker(Comparator(stocksDict));
类型。
答案 1 :(得分:0)
Swift中的字符串是值类型。对于所有值类型,将创建现有String值的新副本。
来自Apple Document。
Swift的默认复制String行为确保了当一个函数 或者方法传递给你一个String值,显然你拥有它 精确的字符串值,无论它来自何处。你可以 确信您传递的字符串不会被修改,除非 你自己修改它。
希望这有帮助