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

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

快来动手试试吧!

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

相关文章
|
数据安全/隐私保护 Swift
Swift实用小册26: 正则表达式的使用
在本章中,你将学会常用的正则表达式的使用方法。
257 3
Swift实用小册26: 正则表达式的使用
|
存储 Swift
Swift实用小册25: 高级运算符之位运算符的使用
在本章中,你将学会高级运算符的位运算符的使用方法。
207 0
Swift实用小册25: 高级运算符之位运算符的使用
|
数据安全/隐私保护 Swift 索引
Swift实用小册24: AccessControl访问控制的使用
在本章中,你将学会AccessControl访问控制的使用方法。
149 0
Swift实用小册24: AccessControl访问控制的使用
|
Swift
Swift实用小册22: OpaqueTypes不透明类型的使用
在本章中,你将学会OpaqueTypes不透明类型的使用方法。
243 0
Swift实用小册22: OpaqueTypes不透明类型的使用
|
Swift
Swift实用小册21: Generics泛型的使用
在本章中,你将学会Generics泛型的使用方法。
149 0
Swift实用小册21: Generics泛型的使用
|
存储 前端开发 Swift
Swift实用小册20: Protocol协议的使用
在本章中,你将学会Protocol协议的使用方法。
222 0
Swift实用小册20: Protocol协议的使用
|
存储 前端开发 Swift
Swift实用小册19:Extension扩展的使用
在本章中,你将学会Extension扩展的使用方法。
313 0
Swift实用小册19:Extension扩展的使用
|
Swift
Swift实用小册18:NestedTypes嵌套类型的使用
在本章中,你将学会NestedTypes嵌套类型的使用方法。
188 0
Swift实用小册18:NestedTypes嵌套类型的使用
|
存储 Swift
Swift实用小册17:类型检查和类型转换
在本章中,你将学会类型检查和类型转换的使用方法。
130 0
Swift实用小册17:类型检查和类型转换
|
Swift
Swift实用小册16:ErrorHandling异常处理的使用
错误处理(Error handling),是响应错误以及从错误中恢复的过程。 在Swift开发过程中,我们常常会遇到由于一些方法无法执行或者参数丢失等原因导致的系统报错问题,严重一点可能会导致系统奔溃。而错误处理(Error handling),正是当这样那样的问题发生时,系统能够检测到错误并告知我们。
318 0
Swift实用小册16:ErrorHandling异常处理的使用