Swift教程之类的析构详解

在一个类的实例被释放之前,析构函数会被调用。用关键字deinit来定义析构函数,类似于初始化函数用init来定义。析构函数只适用于class类型。

1、析构过程原理

Swift 会自动释放不再需要的实例以释放资源。如自动引用计数那一章描述,Swift 通过自动引用计数(ARC)处理实例的内存管理。通常当你的实例被释放时不需要手动地去清理。但是,当使用自己的资源时,你可能需要进行一些额外的清理。例如,如果创建了一个自定义的类来打开一个文件,并写入一些数据,你可能需要在类实例被释放之前关闭该文件。

在类的定义中,每个类最多只能有一个析构函数。析构函数不带任何参数,在写法上不带括号:

复制代码 代码如下:

deinit {
// 执行析构过程
}

析构函数是在实例释放发生前一步被自动调用。不允许主动调用自己的析构函数。子类继承了父类的析构函数,并且在子类析构函数实现的最后,父类的析构函数被自动调用。即使子类没有提供自己的析构函数,父类的析构函数也总是被调用。

因为直到实例的析构函数被调用时,实例才会被释放,所以析构函数可以访问所有请求实例的属性,并且根据那些属性可以修改它的行为(比如查找一个需要被关闭的文件的名称)。

2、析构器操作

这里是一个析构函数操作的例子。这个例子是一个简单的游戏,定义了两种新类型,Bank和Player。Bank结构体管理一个虚拟货币的流通,在这个流通中Bank永远不可能拥有超过 10,000 的硬币。在这个游戏中有且只能有一个Bank存在,因此Bank由带有静态属性和静态方法的结构体实现,从而存储和管理其当前的状态。

复制代码 代码如下:

struct Bank {
static var coinsInBank = 10_000
static func vendCoins(var numberOfCoinsToVend: Int) -> Int {
numberOfCoinsToVend = min(numberOfCoinsToVend, coinsInBank)
coinsInBank -= numberOfCoinsToVend
return numberOfCoinsToVend
}
static func receiveCoins(coins: Int) {
coinsInBank += coins
}
}

Bank根据它的coinsInBank属性来跟踪当前它拥有的硬币数量。银行还提供两个方法——vendCoins和receiveCoins——用来处理硬币的分发和收集。

vendCoins方法在 bank 分发硬币之前检查是否有足够的硬币。如果没有足够多的硬币,Bank返回一个比请求时小的数字(如果没有硬币留在 bank 中就返回 0)。vendCoins方法声明numberOfCoinsToVend为一个变量参数,这样就可以在方法体的内部修改数字,而不需要定义一个新的变量。vendCoins方法返回一个整型值,表明了提供的硬币的实际数目。

receiveCoins方法只是将 bank 的硬币存储和接收到的硬币数目相加,再保存回 bank。

Player类描述了游戏中的一个玩家。每一个 player 在任何时刻都有一定数量的硬币存储在他们的钱包中。这通过 player 的coinsInPurse属性来体现:

复制代码 代码如下:

class Player {
var coinsInPurse: Int
init(coins: Int) {
coinsInPurse = Bank.vendCoins(coins)
}
func winCoins(coins: Int) {
coinsInPurse += Bank.vendCoins(coins)
}
deinit {
Bank.receiveCoins(coinsInPurse)
}
}

每个Player实例都由一个指定数目硬币组成的启动额度初始化,这些硬币在 bank 初始化的过程中得到。如果没有足够的硬币可用,Player实例可能收到比指定数目少的硬币。

Player类定义了一个winCoins方法,该方法从银行获取一定数量的硬币,并把它们添加到玩家的钱包。Player类还实现了一个析构函数,这个析构函数在Player实例释放前一步被调用。这里析构函数只是将玩家的所有硬币都返回给银行:

复制代码 代码如下:

var playerOne: Player? = Player(coins: 100)
println(“A new player has joined the game with (playerOne!.coinsInPurse) coins”)
// 输出 “A new player has joined the game with 100     coins”
println(“There are now (Bank.coinsInBank) coins left     in the bank”)
// 输出 “There are now 9900 coins left in the bank”

一个新的Player实例随着一个 100 个硬币(如果有)的请求而被创建。这个Player实例存储在一个名为playerOne的可选Player变量中。这里使用一个可选变量,是因为玩家可以随时离开游戏。设置为可选使得你可以跟踪当前是否有玩家在游戏中。

因为playerOne是可选的,所以由一个感叹号(!)来修饰,每当其winCoins方法被调用时,coinsInPurse属性被访问并打印出它的默认硬币数目。

复制代码 代码如下:

playerOne!.winCoins(2_000)
println(“PlayerOne won 2000 coins & now has \    (playerOne!.coinsInPurse) coins”)
// 输出 “PlayerOne won 2000 coins & now has 2100 coins”
println(“The bank now only has (Bank.coinsInBank) coins left”)
// 输出 “The bank now only has 7900 coins left”

这里,player 已经赢得了 2,000 硬币。player 的钱包现在有 2,100 硬币,bank 只剩余 7,900 硬币。

复制代码 代码如下:

playerOne = nil
println(“PlayerOne has left the game”)
// 输出 “PlayerOne has left the game”
println(“The bank now has (Bank.coinsInBank) coins”)
// 输出 “The bank now has 10000 coins”

玩家现在已经离开了游戏。这表明是要将可选的playerOne变量设置为nil,意思是“没有Player实例”。当这种情况发生的时候,playerOne变量对Player实例的引用被破坏了。没有其它属性或者变量引用Player实例,因此为了清空它占用的内存从而释放它。在这发生前一步,其析构函数被自动调用,其硬币被返回到银行。

时间: 2015-01-09

详解Swift语言中的类与结构体

类 在 Swift 中类是建立灵活的构建块.类似于常量,变量和函数,用户可以定义的类的属性和方法.Swift给我们提供了声明类,而无需用户创建接口和实现文件的功能.Swift 允许我们创建类作为单个文件和外部接口,将默认在类一次初始化来创建. 使用类的好处: 继承获得一个类的属性到其他类 类型转换使用户能够在运行时检查类的类型 初始化器需要处理释放内存资源 引用计数允许类实例有一个以上的参考 类和结构的共同特征: 属性被定义为存储值 下标被定义为提供访问值 方法被初始化来改善功能 初始状态是由初

Swift教程之类与结构详解

类与结构是编程人员在代码中会经常用到的代码块.在类与结构中可以像定义常量,变量和函数一样,定义相关的属性和方法以此来实现各种功能. 和其它的编程语言不太相同的是,Swift不需要单独创建接口或者实现文件来使用类或者结构.Swift中的类或者结构可以在单文件中直接定义,一旦定义完成后,就能够被直接其它代码使用. 注意:一个类的实例一般被视作一个对象,但是在Swift中,类与结构更像是一个函数方法,在后续的章节中更多地是讲述类和结构的功能性. 1.类和结构的异同 类和结构有一些相似的地方,它们都可以

Swift中的类class与结构体struct体学习笔记

一.引言 Swift中的类与结构体十分相似,和Objective-C不同的事,Swift中的结构体不仅可以定义属性,也可以像类一样为其定义方法. Swift中的类与结构体有如下相似点: 1.定义属性来存储值. 2.定义函数来提供功能. 3.通过定义下标语法使用下标的方式取值. 4.定义构造方法来对其进行初始化. 5.通过扩展来在原始基础上添加功能. 6.通过协议来定义实现标准. 当然类和结构体也有许多不同点,下面这些功能是类独有的,结构体没有: 1.通过继承来创建类的子类. 2.在运行时允许对类

Python中列表、字典、元组数据结构的简单学习笔记

列表 列表是Python中最具灵活性的有序集合对象类型.与字符串不同的是,列表可以包含任何类型的对象:数字.字符串甚至其他列表.列表是可变对象,它支持原地修改的操作. Python的列表是: 任意对象的有序集合 通过偏移读取 可变长度.异构以及任意嵌套 属于可变序列的分类 对象引用数组(列表中的存储的是对象的引用,而不是对象的拷贝) 实际应用中的列表 >>基本列表操作 由于列表是序列,它支持很多与字符串相同的操作.列表对"+"和"*"操作的响应与字符串很

老生常谈ES6中的类

前面的话 大多数面向对象的编程语言都支持类和类继承的特性,而JS却不支持这些特性,只能通过其他方法定义并关联多个相似的对象,这种状态一直延续到了ES5.由于类似的库层出不穷,最终还是在ECMAScript 6中引入了类的特性.本文将详细介绍ES6中的类 ES5近似结构 在ES5中没有类的概念,最相近的思路是创建一个自定义类型:首先创建一个构造函数,然后定义另一个方法并赋值给构造函数的原型 function PersonType(name) { this.name = name; } Person

JavaScript学习笔记之取数组中最大值和最小值

推荐阅读:JavaScript学习笔记之数组的增.删.改.查 JavaScript学习笔记之数组求和方法 JavaScript学习笔记之数组随机排序 在实际业务中有的时候要取出数组中的最大值或最小值.但在数组中并没有提供arr.max()和arr.min()这样的方法.那么是不是可以通过别的方式实现类似这样的方法呢?那么今天我们就来整理取出数组中最大值和最小值的一些方法. 取数组中最大值 可以先把思路理一下: 将数组中第一个元素赋值给一个变量,并且把这个变量作为最大值: 开始遍历数组,从第二个元

C++中声明类的class与声明结构体的struct关键字详解

class class 关键字声明类类型或定义类类型的对象. 语法 [template-spec] class [ms-decl-spec] [tag [: base-list ]] { member-list } [declarators]; [ class ] tag declarators; 参数 template-spec 可选模板说明. ms-decl-spec 可选存储类说明有关更多信息 tag 给定于类的类型名称.在类范围内的标记成为了保留字.标志是可选项.如果省略,定义匿名类.

浅谈Go语言中的结构体struct & 接口Interface & 反射

结构体struct struct 用来自定义复杂数据结构,可以包含多个字段(属性),可以嵌套: go中的struct类型理解为类,可以定义方法,和函数定义有些许区别: struct类型是值类型. struct定义 type User struct { Name string Age int32 mess string } var user User var user1 *User = &User{} var user2 *User = new(User) struct使用 下面示例中user1和

C语言中结构体struct编写的一些要点解析

一.关于结构体的声明 1.匿名声明.如: struct { int i,j; }point; 说明: 这段代码的含义是,声明一个无名(anonymous)的结构体,并创建了一个结构体变量point.如果这段声明是放在全局域(在任意函数(比如main函数)外)内,那么point内的变量将被初始化为默认值,换句话说,以这种方式声明结构体变量时就已经为它分配了内存空间. 适用于该结构体只需要产生一个变量!本例中,该匿名结构体将有且仅有point这个结构体变量! 不同的匿名结构体变量,类型是不同的!如

C++结构体struct和类class区别详解

之前因为都在忙着毕业的开题答辩与投稿论文的事宜,一直没有时间更新这个系列的文章.师弟看了上一篇雾中风景的文章,希望我继续把这个系列的文章写下去.坦白说,C++的特性很多,这也不是教学指南的文章,我会选取一些自己在学习C++过程之中值得探讨的问题和大家聊一聊,来抛砖引玉.好的,今天先放点开胃菜,和大家聊聊struct与class关键字. 1.struct关键字: 在C++语言作为C语言的一个超集,是兼容C语言的所有语法规则的.C语言是我学习的第一门编程语言,我自然对于其中的语法规则十分熟悉,C语言

在Swift中使用Objective-C编写类、继承Objective-C类

互用性(互操作性)使开发者可以定义融合了 Objective-C 语言特性的Swift类.编写 Swift 类时,不仅可以继承 Objective-C 语言编写的父类,采用 Objective-C 的协议,还可以利用 Objective-C 的一些其它功能.这意味着,开发者可以基于 Objective-C 中已有的熟悉.可靠的类.方法和框架来创建 Swift 类,并结合 Swift 提供的现代化和更有效的语言特点对其进行优化. 继承Objective-C的类 在 Swift 中,开发者可以定义一