How to copy a "Dictionary" in Swift?

26,218

Solution 1

A 'Dictionary' is actually a Struct in swift, which is a value type. So copying it is as easy as:

let myDictionary = ...
let copyOfMyDictionary = myDictionary

To copy an object (which is a reference type) has a couple of different answers. If the object adopts the NSCopying protocol, then you can just do:

let myObject = ...
let copyOfMyObject = myObject.copy()

If your object doesn't conform to NSCopying then you may not be able to copy the object. Depending on the object's class it may provide it's own method to get a duplicate copy, or if the object has no internal private state then you could create a new object with the same properties.

[Edited to correct a mistake in the previous answer - NSObject (both the Class and the Protocol) does not provide a copy or copyWithZone method and therefore is insufficient for being able to copy an object]

Solution 2

All of the answers given here are great, but they miss a key point regarding warning you about the caveats of copying.

In Swift, you have either value types (struct, enum, tuple, array, dict etc) or reference types (classes).

If you need to copy a class object, then, you have to implement the methods copyWithZone in your class and then call copy on the object.

But if you need to copy a value type object, for eg. an Array you can copy it directly by just assigning it to a new variable like so:

let myArray = ...
let copyOfMyArray = myArray

But this is only shallow copying.

If your array contains class objects and you want to make their copy as well then you have to copy each array element individually. This will allow you to make a deep copy.

This is extra information that I thought would add to the information already presented in the well-written answers above.

Solution 3

Object

class Person: NSObject, NSCopying {
    var firstName: String
    var lastName: String
    var age: Int

    init(firstName: String, lastName: String, age: Int) {
        self.firstName = firstName
        self.lastName = lastName
        self.age = age
    }

    func copyWithZone(zone: NSZone) -> AnyObject {
        let copy = Person(firstName: firstName, lastName: lastName, age: age)
        return copy
    }
}

Usage

let paul = Person(firstName: "Paul", lastName: "Hudson", age: 35)
let sophie = paul.copy() as! Person

sophie.firstName = "Sophie"
sophie.age = 5

print("\(paul.firstName) \(paul.lastName) is \(paul.age)")
print("\(sophie.firstName) \(sophie.lastName) is \(sophie.age)")

Source: https://www.hackingwithswift.com/example-code/system/how-to-copy-objects-in-swift-using-copy

Share:
26,218
allenlinli
Author by

allenlinli

Swifter Swift!

Updated on October 17, 2020

Comments

  • allenlinli
    allenlinli over 3 years

    How to copy a "Dictionary" in Swift?

    That is, get another object with same keys/values but different memory address.

    Furthermore, how to copy an object in Swift?

    Thanks,

  • allenlinli
    allenlinli over 7 years
    I did ask about this in my another ST question :).
  • Todd
    Todd about 3 years
    Looking at the code you've copied from the article, have you forgotten the correct method signature? I.e.: copy(with zone: NSZone? = nil)