前言
和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
以上就是本章的全部内容。
快来动手试试吧!
如果本专栏对你有帮助,不妨点赞、评论、关注~