Swift uses automatic reference counting (ARC) to track and manage application memory
Usually we don’t need to free memory manually because ARC automatically frees up memory when an instance of a class is no longer in use.
But sometimes we still need to implement memory management in our code. When each time you use The memory contains the type information of the instance, as well as the values of all related properties of the instance. When the instance is no longer in use, ARC frees up the memory occupied by the instance and allows the freed memory to be diverted to other uses. To ensure that instances in use are not destroyed, ARC tracks and calculates how many properties, constants, and variables each instance is being referenced. Instance is assigned to a property, constant, or variable, all of which create a strong reference to the instance, and the instance is not allowed to be destroyed as long as the strong reference is there. The output of the above program execution is as follows: In the above example, ARC will track your newly created However, we might write code that a class will never have 0 strong references. This happens when two class instances maintain a strong reference to each other and keep each other from being destroyed. This is the so-called cyclic strong reference. An example of inadvertently generating loop strong references is shown below. The example defines two classes: Swift provides two ways to solve the loop strong reference problem you encounter when using the properties of a class: Weak reference No master reference Weak references and unowned references allow one instance of a circular reference to reference another instance without maintaining a strong reference. In this way, instances can refer to each other without generatingcircular strong references. For the lifecycle to become The output of the above program execution is as follows: The output of the above program execution is as follows: A circular strong reference also occurs when you assign a closure to a property of a class instance, and the instance is used in the closure body. Some property of the instance may be accessed in this closure, such as The following example shows you when a closure references the Instance of Solve the loop strong reference caused by the closure: define the capture list as part of the closure when defining the closure, which can solve the loop strong reference between the closure and the class instance. When closures and captured instances always refer to each other and are always destroyed at the same time, the capture within the closure is definedas an unowned reference. Conversely, when a reference is captured, it may sometimes be If the captured reference is never set to Front The output of the above program execution is as follows:
最近几年来,地理信息系统无论是在理论上还是应用上都处在一个飞速发展的阶段。 GIS被应用于多个领域的建模和决策支持,如城市管理、区划、环境整治等等,地理信息成为信息时代重要的组成部分之一; “数字地球”概念的提出,更进一步推动了作为其技术支撑的GIS的发展。 与此同时,一些学者致力于相关的理论研究,如空间感知、空间数据误差、空间关系的形式化等等。 这恰好说明了地理信息系统作为应用技术和学科的两个方面,并且这两个方面构成了相互促进的发展过程。 9.40.1. ARC function #
init() method to create a new instance of a class, ARC allocates a large chunk of memory to store the instance’s information. 9.40.2. ARC instance #
class Person { let name: String init(name: String) { self.name = name print("\(name) Start initialization") } deinit { print("\(name) Deconstructed") } } // The value will be automatically initialized to nil and will not be referenced to an instance of the Person class yet var reference1: Person? var reference2: Person? var reference3: Person? // Create a new instance of the Person class reference1 = Person(name: "Runoob") //Assign values to the other two variables, and this instance will have two additional strong references reference2 = reference1 reference3 = reference1 //Break the first strong reference Reference1=nil //Break the second strong reference Reference2=nil //Break the third strong reference and call the destructor function Reference3=nil Runoob initialization begins Runoob is deconstructed
9.40.3. Cyclic strong references between class instances #
Person the number of references to the instance, and will be found in the Person destroy the instance when it is no longer needed. 9.40.4. Example #
Person and Apartment to model the apartment and its residents:class Person { let name: String init(name: String) { self.name = name } var apartment: Apartment? deinit { print("\(name) is deconstructed") } } class Apartment { let number: Int init(number: Int) { self.number = number } var tenant: Person? deinit { print("Apartment #\(number) is deconstructed") } } //Both variables are initialized to nil Var runoob: Person? Var number73: Apartment? //Assignment Runoob=Person (name: "Runoob") Number73=Apartment (number: 73) //The exclamation mark is used to expand and access instances in the optional variables runoob and number73 //Circular strong reference created Runoob Apartment=number73 Number73 Tenant=runoob //When breaking the strong references held by runoob and number73 variables, the reference count does not drop to 0, and the instance is not destroyed by ARC //Note that when you set these two variables to nil, none of the destructors are called. //The strong reference loop prevents the destruction of instances of the Person and Apartment classes, and causes a memory leak in your application Runoob=nil Number73=nil 9.40.5. Resolve cyclic strong references between instances #
nil uses weak references for an instance ofthe on the contrary, after initializing the assignment, it is no longer assigned to nil , using no primary reference 9.40.6. Weak reference instance #
class Module { let name: String init(name: String) { self.name = name } var sub: SubModule? deinit { print("\(name) main module") } } class SubModule { let number: Int init(number: Int) { self.number = number } weak var topic: Module? deinit { print("The number of sub module topics is \(number)") } } var toc: Module? var list: SubModule? toc = Module(name: "ARC") list = SubModule(number: 4) toc!.sub = list list!.topic = toc toc = nil list = nil ARC main module The number of sub module topics is 4
9.40.7. No primary reference instance #
class Student { let name: String var section: Marks? init(name: String) { self.name = name } deinit { print("\(name)") } } class Marks { let marks: Int unowned let stname: Student init(marks: Int, stname: Student) { self.marks = marks self.stname = stname } deinit { print("The student's score is \(marks)") } } var module: Student? module = Student(name: "ARC") module!.section = Marks(marks: 98, stname: module!) module = nil ARC The student's score is 98
9.40.8. Loop strong reference caused by closure #
self.someProperty or a method of the instance is called in the closure, such as self.someMethod . In both cases, the closure “captures” the self, resulting in a circular strong reference. 9.40.9. Example #
self . How to generate a loop strong reference after. An example is defined called HTMLElement , represented by a simple model HTML a single element:class HTMLElement { let name: String let text: String? lazy var asHTML: () -> String = { if let text = self.text { return "<\(self.name)>\(text)" } else { return "<\(self.name) />" } } init(name: String, text: String? = nil) { self.name = name self.text = text } deinit { print("\(name) is being deinitialized") } } // Create an instance and print information var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world") print(paragraph!.asHTML()) HTMLElement class produces class instances and asHTML a loop strongreference between the closures of the default. asHTML property holds a strong reference to the closure. However, the closure uses self (referenced by the self.name and self.text so the closure captures the self , which means that the closure in turn holds the HTMLElement a strong reference to the instance. In this way, the two objects produce a circular strong reference. 9.40.10. Weak reference and non-primary reference #
nil defines the capture within the closure as a weak reference. nil a headless reference should be used instead of a weak reference 9.40.11. Example #
HTMLElement in the example, no master reference is the correct way to solve the problem of circular strong reference. Write like this HTMLElement class to avoid circular strong references:class HTMLElement { let name: String let text: String? lazy var asHTML: () -> String = { [unowned self] in if let text = self.text { return "<\(self.name)>\(text)" } else { return "<\(self.name) />" } } init(name: String, text: String? = nil) { self.name = name self.text = text } deinit { print("\(name) is deconstructed") } } //Create and print HTMLElement instances var paragraph: HTMLElement? = HTMLElement(name: "p", text: "hello, world") print(paragraph!.asHTML()) // The HTMLElement instance will be destroyed and the message printed by its destructor will be visible paragraph = nil <p>hello, worldp> p is deconstructed