Swift实用小册23: ARC自动引用计数机制的使用

简介: 在本章中,你将学会ARC自动引用计数机制的使用方法。

image.png

前言


Apple官网或者网上分享的教程类文章不同,我将以实际开发角度讲述Swift语言的一些概念和用法,方便大家更好地学习和掌握Swift语言。

这同时也是对自己学习Swift语言过程的知识整理。

如有错误,以你为准。

项目创建


我们新建一个PlayGround项目,命名为SwiftARC

image.png

ARC的定义


ARC自动引用计数机制,是Swift官方提供的一种跟踪和管理应用程序的内存的机制。

ARC可以帮助我们设计的应用程序自动释放内存,保证我们实例在使用完成后不会占用内存资源,保障应用程序运行的流畅性。

ARC的功能


使用init()方法创建一个类的实例时,ARC会分配内存用来储存实例的信息,内存中会包含实例的类型信息,以及这个实例所有相关属性的值。

当实例不再被使用时,ARC释放实例所占用的内存。为了确保使用中的实例不会被销毁,ARC会跟踪和计算每一个实例正在被多少属性,常量和变量所引用。

实例赋值给属性、常量或变量,都会创建实例的强引用,只要强引用还在,实例就不会被销毁。

ARC的使用


我们用之前Destructor析构函数的例子展示ARC自动引用计数机制的使用。示例:

class appInformation {
    var appName: String
    var appVersion: String
    var appAuthor: String
    // 构造函数
    init(appName: String, appVersion: String, appAuthor: String) {
        self.appName = appName
        self.appVersion = appVersion
        self.appAuthor = appAuthor
        print("调用构造函数")
    }
    // 析构函数
    deinit {
        print("调用析构函数")
    }
}

image.png

上述代码中,我们定义了一个appInformation类,然后声明了三个String类型的变量:appNameappVersionappAuthor

appInformation类有一个构造器,构造器给实例的变量属性赋值,然后打印一条信息:调用构造函数

appInformation类有一个析构器,析构器在实例被销毁时打印一条信息:调用析构函数

强引用


接下来,我们创建一个实例。

var app: appInformation?
app = appInformation(appName: "Swift实用小册", appVersion: "1.0.0", appAuthor: "文如秋雨”)
app = nil

image.png

上述代码中,我们创建了一个appInformation类的实例:app,并将appInformation实例赋值给了app

这样在我们调用appInformation构造器时,会打印输出一条信息:调用构造函数

由于appInformation实例赋值给了app变量,因此app变量和appInformation实例之间会建立一个强引用

又由于这个强引用的存在,ARC自动引用计数机制会保证appInformation实例会保存在内存中不会被销毁。

当我们要断开强引用时,我们可以通过给app变量赋值nil,这样这个强引用就会被断开,appInformation实例也就会被销毁,从而释放内存。

弱引用


在上面的例子中,ARC会跟踪我们创建的appInformation实例的引用数量,并且在不需要用到的时候销毁它。

但如果我们使用2个或以上的类的实例,然后它们之间互相建立强引用,这就导致永远都不可能释放这部分的内存。

这是一个很严重的问题。

因此,我们引用了弱引用的概念。

弱引用能保证我们在多个实例循环引用时不保持强引用的状态。示例:

class Model1 {
    let name: String
    init(name: String) { self.name = name }
    var strongModel: Model2?
    deinit { print("释放") }
}
class Model2 {
    let title: String
    init(title: String) { self.title = title }
    weak var weakModel: Model1?
    deinit { print("释放") }
}

image.png

上述代码中,我们创建了2个类:Model1Model2,并都对其进行初始化。

然后在Model1类中强引用Model2类,在Model2类中弱引用Model1类,然后我们建立两个变量model1model2之间的强引用,并关联两个实例:

var model1: Model1?
var model2: Model2?
model1 = Model1(name: "文如秋雨")
model2 = Model2(title: "Swift实用小册”)
model1 = nil

image.png

如果这时候,我们将model1的强引用断开,那么类Model1的实例就会被销毁,又由于我们Model2使用弱引用,这时候就不会循环创建两个类的实例的强引用关系,导致两个实例都占用内存

本章代码


import UIKit
class appInformation {
    var appName: String
    var appVersion: String
    var appAuthor: String
    // 构造函数
    init(appName: String, appVersion: String, appAuthor: String) {
        self.appName = appName
        self.appVersion = appVersion
        self.appAuthor = appAuthor
        print("调用构造函数")
    }
    // 析构函数
    deinit {
        print("调用析构函数")
    }
}
var app: appInformation?
app = appInformation(appName: "Swift实用小册", appVersion: "1.0.0", appAuthor: "文如秋雨")
app = nil
class Model1 {
    let name: String
    init(name: String) { self.name = name }
    var strongModel: Model2?
    deinit { print("释放") }
}
class Model2 {
    let title: String
    init(title: String) { self.title = title }
    weak var weakModel: Model1?
    deinit { print("释放") }
}
var model1: Model1?
var model2: Model2?
model1 = Model1(name: "文如秋雨")
model2 = Model2(title: "Swift实用小册")
model1 = nil

以上就是本章的全部内容。

快来动手试试吧!

如果本专栏对你有帮助,不妨点赞、评论、关注~

相关文章
|
1月前
|
Swift
Swift 自动引用计数(ARC)
Swift 自动引用计数(ARC)
28 1
|
7月前
|
Swift 开发者
【Swift开发专栏】Swift中的内存管理ARC机制
【4月更文挑战第30天】Swift的Automatic Reference Counting (ARC)自动管理内存,通过跟踪对象引用实现对象的释放。当引用计数为0时,系统回收内存。引用计数在变量赋值时增加,引用移除时减少。循环引用可能导致内存泄漏,Swift通过weak(可选)和unowned(非空)引用解决此问题,根据对象生命周期选择合适类型。理解ARC和正确处理循环引用是关键。
135 0
|
数据安全/隐私保护 Swift
Swift实用小册26: 正则表达式的使用
在本章中,你将学会常用的正则表达式的使用方法。
302 3
Swift实用小册26: 正则表达式的使用
|
存储 Swift
Swift实用小册25: 高级运算符之位运算符的使用
在本章中,你将学会高级运算符的位运算符的使用方法。
253 0
Swift实用小册25: 高级运算符之位运算符的使用
|
数据安全/隐私保护 Swift 索引
Swift实用小册24: AccessControl访问控制的使用
在本章中,你将学会AccessControl访问控制的使用方法。
201 0
Swift实用小册24: AccessControl访问控制的使用
|
Swift
Swift实用小册22: OpaqueTypes不透明类型的使用
在本章中,你将学会OpaqueTypes不透明类型的使用方法。
293 0
Swift实用小册22: OpaqueTypes不透明类型的使用
|
Swift
Swift实用小册21: Generics泛型的使用
在本章中,你将学会Generics泛型的使用方法。
183 0
Swift实用小册21: Generics泛型的使用
|
存储 前端开发 Swift
Swift实用小册20: Protocol协议的使用
在本章中,你将学会Protocol协议的使用方法。
279 0
Swift实用小册20: Protocol协议的使用
|
存储 前端开发 Swift
Swift实用小册19:Extension扩展的使用
在本章中,你将学会Extension扩展的使用方法。
408 0
Swift实用小册19:Extension扩展的使用
|
Swift
Swift实用小册18:NestedTypes嵌套类型的使用
在本章中,你将学会NestedTypes嵌套类型的使用方法。
223 0
Swift实用小册18:NestedTypes嵌套类型的使用