Swift实用小册23: ARC自动引用计数机制的使用
【摘要】 在本章中,你将学会ARC自动引用计数机制的使用方法。前言和Apple官网或者网上分享的教程类文章不同,我将以实际开发角度讲述Swift语言的一些概念和用法,方便大家更好地学习和掌握Swift语言。这同时也是对自己学习Swift语言过程的知识整理。如有错误,以你为准。项目创建我们新建一个PlayGround项目,命名为SwiftARC。ARC的定义ARC,自动引用计数机制,是Swift官方提供...
在本章中,你将学会ARC自动引用计数机制的使用方法。
前言
和Apple官网或者网上分享的教程类文章不同,我将以实际开发角度讲述Swift语言的一些概念和用法,方便大家更好地学习和掌握Swift语言。
这同时也是对自己学习Swift语言过程的知识整理。
如有错误,以你为准。
项目创建
我们新建一个PlayGround项目,命名为SwiftARC。
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("调用析构函数")
}
}
上述代码中,我们定义了一个appInformation类,然后声明了三个String类型的变量:appName、appVersion、appAuthor。
appInformation类有一个构造器,构造器给实例的变量属性赋值,然后打印一条信息:调用构造函数。
appInformation类有一个析构器,析构器在实例被销毁时打印一条信息:调用析构函数。
强引用
接下来,我们创建一个实例。
var app: appInformation?
app = appInformation(appName: "Swift实用小册", appVersion: "1.0.0", appAuthor: "文如秋雨”)
app = nil
上述代码中,我们创建了一个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("释放") }
}
上述代码中,我们创建了2个类:Model1、Model2,并都对其进行初始化。
然后在Model1类中强引用Model2类,在Model2类中弱引用Model1类,然后我们建立两个变量model1、model2之间的强引用,并关联两个实例:
var model1: Model1?
var model2: Model2?
model1 = Model1(name: "文如秋雨")
model2 = Model2(title: "Swift实用小册”)
model1 = nil
如果这时候,我们将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
以上就是本章的全部内容。
快来动手试试吧!
如果本专栏对你有帮助,不妨点赞、评论、关注~
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)