Deep Copy and Shallow Copy in iOS

Whether dealing with collection objects or non-collection objects, when they receive and messages, the following rules apply: - returns an object. Therefore, calling mutable interface methods on a return value will cause a crash. - returns a object. and for Non-Collection Objects Non-collection system objects refer to types like and . Let's start with an example of copying an non-collection object: By examining the memory addresses, we can see that and share the same address — this is a pointer copy. , however, has a different address from , indicating a content copy. Now let's look at copying a object: The crash occurs because returns an object. After commenting out that line, running the code shows that all four objects — , , , and — have different memory addresses, meaning all of them performed content copies. For non-collection objects: performing on an object is a pointer copy; is a content copy. Both and on a object are content copies. In short: - [immutableObject copy] // Shallow copy - [immutableObject mutableCopy] // Deep copy - [mutableObject copy] // Deep copy - [mutableObject mutableCopy] // Deep copy and for Collection Objects Collection objects refer to types like , , and . Let's start with an example of using and on an collection: We can see that and share the same address, while and have different addresses. This means performed a pointer copy, and performed a content copy. However, it's important to note: this content copy only copies the object itself — the elements inside the array are still pointer copies. This is quite similar to the immutable non-collection case. Let's check whether the same holds for collections: As expected, , , and all have different addresses, confirming that both and performed content copies of . We can therefore conclude: For collection objects: on an object is a pointer copy; is a content copy. Both and on a object are content copies. However: the content copy only applies to the collection object itself — its elements remain pointer copies. In short: [immutableObject copy] // Shallow copy [immutableObject mutableCopy] // One-level-deep copy [mutableObject copy] // One-level-deep copy [mutableObject mutableCopy] // One-level-deep copy This conclusion is very similar to the non-collection case. But what if you need to copy the elements inside the collection? If you have a multi-level array and perform a content copy on only the first level while the other levels remain pointer copies, is this a deep copy or a shallow copy? On this topic, the Apple documentation states: This kind of copy is only capable of producing a one-level-deep copy. If you only need a one-level-deep copy, you can explicitly call for one as in Listing 2 Listing 2 Making a deep copy This technique applies to the other collections as well. Use the collection's equivalent of initWithArray:copyItems: with YES as the second parameter. Apple considers this type of copy not a true deep copy, calling it instead a one-level-deep copy. If you need a true deep copy, such as when you have an array of arrays, you can archive and then unarchive the collection, provided the contents all conform to the NSCoding protocol. An example of this technique is shown in Listing 3. Listing 3 A true deep copy For a truly complete copy, you need: Summary: - Shallow copy: Every level of the copied object is a pointer copy. - Deep copy (one-level-deep): At least one level of the copied object is a content copy. - True deep copy (real-deep copy): Every level of the copied object is a content copy. Additional note: Here, the memory address is being changed. The second line should be understood as: is a new object, and its memory address is assigned to . Reference: Deep Copy and Shallow Copy in iOS Collections