Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 4 Copy arrays by value

I have an array var arr = [myObject] I want to copy it to arr2 so that modifying object in the second the first remained as is (copy by value). How to make it?

like image 347
AlexP Avatar asked Apr 07 '18 11:04

AlexP


1 Answers

If the type within your array is an enum or a struct, no problem. You don't need to think about it:

var a = [1,2,3]
var b = a
b[1] = 3
b // [1, 3, 3]
a // [1, 2, 3]

If your array contains a class then you do need to think about how you copy objects, because by default you will be working with pointers to the same instances:

let ns = NSMutableArray()
var arr = [ns]
var arr2 = arr

arr2[0].add(2)
arr[0] // [2]

But where classes adopt the NSCopying protocol you can use copy() and mutableCopy() to make the necessary copies to resolve this:

var arr3 = arr.map(){$0.mutableCopy() as! NSMutableArray}
arr3[0].add(1)
arr3[0] // [2, 1]
arr[0] // [2]
arr2[0] // [2]

Where a class does not adopt the NSCopying protocol, you will need to extend or subclass, adding a copy(with:) method:

extension UIView: NSCopying {
    public func copy(with zone: NSZone? = nil) -> Any {
        return UIView(frame: self.frame)
    }
}

var aView = UIView(frame:CGRect(x: 0, y: 0, width: 100, height: 100))
var bView = aView.copy() as! UIView

aView.tag = 5
bView.tag // 0
aView.tag // 5

Note: The code example of copying a UIView is incredibly simplistic and assumes that a "copy" is simply a view the same size, whereas a copy in real use would be something more complex, most likely containing subviews, etc.

like image 162
sketchyTech Avatar answered Nov 13 '22 22:11

sketchyTech