There seems to be a lot of confusion and different opinions on this out there, I want to know, is that possible in swift to make a shallow copy of an object and not a deep copy.
I checked in JAVA - http://www.jusfortechies.com/java/core-java/deepcopy_and_shallowcopy.php, It's clearly explained the difference between shallow copy and deep copy with example, but I didn't got kind of example in swift.
I tried initWithArray:copyItems: to check what difference does it make when I'm changing the Boolean flag of copyItems, but none of the difference I see. I supposed to have difference of shallow or deep copy by changing the copyItems flag, but I was wrong it creates a deep copy always.
Please check my below code, I cloned the array object arrayObject1 to arrayObject2 using initWithArray:copyItems: by setting copyItems: to true. I changed the arrayObject2 0th string object to new string object and arrayObject2 0th object changed, but arrayObject1 0th object didn't changed. whereas if I'm copying it by assigning copyItems: to false, then also I'm having the same result.
So how to achieve a shallow copy and if it's not by initWithArray:copyItems: then what copyItems: flag making impact on result.
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)
}
It happens because name
is a Swift String instance. String is struct, thus it's a value type. That is because it's always copied by value. arrayObject1 as [AnyObject]
is a conversion to swift Array (a struct too) with String objects within.
So it's not trivial to get a shallow copy using such structures like Array and String in Swift.
I can only come up with an idea of boxing struct instances into a class wrapper:
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()
It gives me a following output:
john
john