The content list

  1. Depth copy
  2. String copy
  3. A copy of the collection class
  4. Local temporary objects and global objects
  5. The declaration cycle of a type attribute
  6. Implicit strong references – collection classes, timers, tuples
  7. Loop strong references caused by closure properties
  8. Resolve the problem of strong references to closure attributes

The detailed content

1. Deep and light copy

The concept of deep copy and shallow copy is very important in iOS development. The difference between the two concepts is that deep copy is to create a new space to copy an object and put it in, that is, the old and the new are identical, but are two independent individuals. One of the objects changes its value. The other object is not affected. Shallow copy creates a space in memory that does not contain the newly copied object. In other words, the newly created space does not store the new copy object. In other words, when you change the properties of the object, the copy content will also change.

Code demo

  

<! -- Structure. Struct DeepCopy {var copy: Int = 0} <! --> class ShallowCopy {var copy: Int = 0} var d0 = DeepCopy(copy: 90) var d1 = d0 d1.copy = 9 print("d0.copy : \(d0.copy)") print("d1.copy : \(d1.copy)") print("---- ----") var s0 = ShallowCopy() s0.copy = 2 var s1 = s0 print("s0.copy: \(s0.copy)") print("s1.copy: \(s1.copy)")Copy the code

The print information

D1. copy: 90 d1.copy: 9 ---- Branch line ---- s1.copy: 2 s1.copy: 2Copy the code

As you can see from the result, assignment for value types is a deep copy, and assignment for reference types is a shallow copy. Memory management is required because assignment operations for application types are shallow copies

2. Copy the string

First of all, there is much content about String copy in OC, which involves a wide range of knowledge points. There is no extended description here, but only a copy introduction of Swift String. There is its own String type String in Swift, and there is also an NSString type of OC. Different types of strings are copied in different ways. See the code below for details.

Code demo

var swiftStr : String = "Hello" var swiftStr1 = swiftStr swiftStr1 += " World" print("swiftStr : \(swiftStr)") print("swiftStr1: \(swiftStr1)") print(" ----") var ocStr = NSMutableString(string: "Hello") var ocStr1 = ocStr ocStr1.insert(ocStr as String, at: ocStr.length) print("ocStr : \(ocStr)") print("ocStr1 : \(ocStr1)")Copy the code

The print information

<! --> swiftStr: Hello <! SwiftStr1: Hello World -- branch line ---- <! Change a value --> ocStr: HelloHello <! --> ocStr1: HelloHelloCopy the code

Swift String is a deep copy, while OC NSMutabliString is a shallow copy. The reason is that you need to click on String and NSMutabliString to check it out (the shortcut is Command + left mouse + what to view).

Click on the message

The String in Swift is a structure, and the value type, as explained above, is a deep copy

Use the NSString class that is commonly used in OC and its subclass NSMutableString, which are classes, reference types, which are shallow copies as explained above

3. Copies of collections

For this combination, I will only introduce the simplest and most superficial array and dictionary. As for whether the contents of the array are value types or reference types, I will not discuss them in depth here, and I will introduce them later. Similarly, the introduction here is divided into classes in Swift and Foundation framework.

Code demo

1. Copy the array
<! Swift array --> var swiftArray: Array <Int> = [1,2,3] var swiftArray1 = swiftArray1 += [4] print("swiftArray1: \(swiftArray1)") print("swiftArray : \(swiftArray)") <! --> var ocArray = NSMutableArray(array: [1, 2, 3 , 4]) var ocArray1 = ocArray ocArray1.add(5) print("ocArray:\(ocArray)") print("ocArray1:\(ocArray1)")Copy the code

The print information

<! SwiftArray1: [1, 2, 3, 4] swiftArray: [1, 2, 3] <! OcArray :(1, 2, 3, 4, 5) ocArray1:(1, 2, 3, 4, 5) ocArray1:(1, 2, 3, 4, 5)Copy the code
2. Copy the dictionary
<! Var swiftDict: Dictionary = [1: "1", 2: "2"] var swiftDict1 = swiftDict swiftDict[3] = "3" print("swiftDict1 :\(swiftDict1)") print("swiftDict :\(swiftDict)") <! Var ocDict = NSMutableDictionary(dictionary: [1: "1", 2: "2", 3: "3"]) var ocDict1 = ocDict ocDict1.addEntries(from: [4 : "4"]) print("ocDict1 :\(ocDict1)") print("ocDict : \(ocDict)")Copy the code

The print information

<! - Swift native dictionary -- -- > swiftDict1: [2: "2", 1: "1"] swiftDict: [2: "2", 3: "3", 1: "1"] <! Dict1 :{3 = 3; 2 = 2; 1 = 1; 4 = 4th; } ocDict : { 3 = 3; 2 = 2; 1 = 1; 4 = 4th; }Copy the code

View type implementation details

1. The Swift array

1.1 OC array

2. Swift dictionary

2.1 OC dictionary

From the above we can see that the Foundation library class objects are all rewritten as reference types in Swift, while Swift native arrays and dictionaries are value types

4. Drill down on copies of collection classes

Here is an in-depth introduction to array copying. The previous array copying is very simple, without discussing whether the elements in the array are deep-copied objects or shallow-copied objects. This is the kind of case that needs to be demonstrated here.

Code demo

Reference the previous code snippet
// Struct. Struct DeepCopy {var copy: Int = 0} class ShallowCopy {var copy: Int = 0}Copy the code
Array copy demo
<! Var de0 = DeepCopy() var de1 = DeepCopy() <! Var deArray = [de0, de1] <! Var sh0 = ShallowCopy() var sh1 = ShallowCopy() <! Var shArray = [sh0, sh1] <! Var deArray1 = deArray var shArray1 = shArray deArray1[0] = DeepCopy(copy: 3) print("deArray[0].copy : \(deArray[0].copy)") print("deArray1[0].copy : \(deArray1[0].copy)") <! Copy = 2 print("shArray[0]. Copy: \(shArray[0].copy)") print("shArray1[0].copy: \(shArray[0].copy)") print("shArray1[0].copy: \ \(shArray1[0].copy)") <! Remove (at: 1) print(" dearray1.count: \(dearray1.count)") print(" dearray1.count: \(dearray1.count)") print(" dearray1.count: \(dearray1.count)") \(deArray.count)") <! Remove (at: 0) print(" sharray1.count: \(sharray1.count)") print(" sharray1.count: \(sharray1.count)") print(" sharray1.count: \ \(shArray.count)")Copy the code

The print information

<! DeArray [0]. Copy: 0 deArray1[0]. Copy: 3 <! ShArray [0]. Copy: 2 shArray1[0]. Copy: 2 <! -- Part 2 --> <! Dearray1.count: 1 dearray. count: 2 <! Sharray. count: 1 sharray. count: 2Copy the code

DeArray and deArray1 are both deep-copy objects. When you modify the attributes of the values in the array, you can see from the printed information: Deep copy elements are not affected by changing the value of their attributes (deArray[0] has a copy value of 0, deArray1[0] has a copy value of 3, and only deArray1[0] has a copy value of 3). However, the shallow-copy elements will change according to the value of the attribute of the modified element (after the attribute value of the element of shArray[0] is changed, the printed information will find that the attribute value of the element of shArray1[0] is also changed). A problem is that the array uses the Swift native structure (value type), and its copy is supposed to be a deep copy, but the previous result shows that the contents of the shArray1 array have changed. Why is that? Let’s move on to the code for the second part of the operation. The deArray1 deep copy array now has one element instead of two. DeArray deep-copy arrays are not affected. The shArray1 shallow-copy array has 2 elements. After removing one element, the number of elements becomes one. The number of elements in shArray1 shallow-copy array is not affected. Then according to the above print information, and summary can be found such a principle: the array in the assignment operation, is a deep copy, this and the elements in the array is a reference type (shallow copy objects) or value type (no deep copy objects), the array at the time of assignment copy, first the system will according to the size of the array is copied open up the size of memory space. Each element in the original array is then copied into the new array object. However, when an array element is modified and its contents are shallow copy objects, the array assigned to the element inside the array will change accordingly, so we can conclude: If the inner element of the array is a reference object, modify the attribute value of the element. The inner element of the array is a shallow copy, that is, if you modify the inner element of the copied array, the elements in the copied array will also change. Conversely, if the inner element is an object of value type, the inner element of the array is a deep copy. Conclusion: Just changing the size of an array does not affect the other array. This article starts with memory management. Memory management will be covered in a future article.