Deinitialization

当类的实例对象即将要被释放时,会立即调用deinitializer,通过deinit关键字来定义deinitializer,和initializer一样,它也只存在于类类型上。

当实例对象不再有用时,Swift会自动释放该对象。Swift通过自动引用计数(ARC)来管理实例内存。通常情况下,对象被释放时,你并不需要做特别的清理,但是,如果你操作了你自己的资源,可能需要做一些额外的清理工作。比如,你在某个类中打开了一个文件,并往里写入了数据,那么你需要在这个类的实例对象释放前关闭文件。

一个类最多只能有一个deinitializer,并且它不接受任何参数,定义方式也是无参数形式:

deinit {
// perform the deinitialization
}

deinitializer是自动在合适的时刻被调用的,你不能手动调用它。

超类的deinitializer会自动被子类继承,并且超类的deinitializer会自动在子类的deinitializer实现完成之后被调用。当然,如果子类并没有提供deinitializer的实现,超类的deinitializer依然会被自动调用。因为实例对象是在deinitializer被调用完成之后才会被释放,因此deinitializer可以访问实例对象的所有属性,并且基于这些属性实现一些操作(比如查询需要被关闭的文件名字)。

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
}
}

这里定义了一个结构体来模拟一个简单的游戏虚拟银行,它负责整个游戏里的货币存储和借贷,它声明了一个类型属性coinsInBank来跟踪银行里面的现金数。这里vendCoins方法定义了一个变量型参数,这样它就不用在方法体内部再声明一个变量然后赋值,而是直接操作这个变量型参数就可以了。

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模拟游戏中的玩家,它声明一个存储属性coinsInPurse来标识这个实例对象当前拥有的金币数。在init和winCoins两个方法中,虽然接受了一个coins参数,但是并不是直接将其赋值给存储属性,而是取决于Bank能够借贷出来的金币数。这里定义了一个deinitializer,在当前实例对象被释放之前将所拥有的金币归还给银行。

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

这里定义了一个可选Player类型变量playerOne,之所以定义为可选类型,是因为该玩家可以随时离开游戏,即该对象随时可能被释放。这里要访问它的存储属性时,用了隐式展开可选项符号(!),同样,在调用它的实例方法时也要这样:

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

当playerOne被释放时,在此之前会先执行它的deinitializer进行相关的清理工作,即将钱还给银行:

playerOne = nil
println("PlayerOne has left the game")
// prints "PlayerOne has left the game"
println("The bank now has \(Bank.coinsInBank) coins")
// prints "The bank now has 10000 coins”

Swift学习笔记十四的更多相关文章

  1. Swift学习笔记十四:构造(Initialization)

         类和结构体在实例创建时,必须为全部存储型属性设置合适的初始值. 存储型属性的值不能处于一个未知的状态.     你能够在构造器中为存储型属性赋初值,也能够在定义属性时为其设置默认值.下面章节 ...

  2. python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例

    python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例 新浪爱彩双色球开奖数据URL:http://zst.aicai.com/ssq/openInfo/ 最终输出结果格 ...

  3. (C/C++学习笔记) 十四. 动态分配

    十四. 动态分配 ● C语言实现动态数组 C语言实现动态数组,克服静态数组大小固定的缺陷 C语言中,数组长度必须在创建数组时指定,并且只能是一个常数,不能是变量.一旦定义了一个数组,系统将为它分配一个 ...

  4. Swift学习笔记十六:协议

    Protocol(协议)用于统一方法和属性的名称,而不实现不论什么功能. 协议可以被类.枚举.结构体实现.满足协议要求的类,枚举,结构体被称为协议的遵循者. 遵循者须要提供协议指定的成员,如属性,方法 ...

  5. Swift 学习笔记(四)

    116.使用可选链式调用代替强制展开 通过在想调用的属性.方法.或下标的可选值(optional value)后面放一个问号(?),可以定义一个可选链.这一点很像在可选值后面放一个叹号(!)来强制展开 ...

  6. 【swift学习笔记】四.swift使用Alamofire和swiftyJson

    Alamofire是AFNetworking的swift版本,功能灰常强大. github:https://github.com/Alamofire/Alamofire SwiftyJSON是操作js ...

  7. SharpGL学习笔记(十四) 材质:十二个材质球

    材质颜色 OpenGL用材料对光的红.绿.蓝三原色的反射率来近似定义材料的颜色.象光源一样,材料颜色也分成环境.漫反射和镜面反射成分,它们决定了材料对环境光.漫反射光和镜面反射光的反射程度.在进行光照 ...

  8. Swift学习笔记十五

    自动引用计数(Automatic Reference Counting) 和OC一样,Swift用自动引用计数机制来跟踪和管理你应用程序的内存,大多数情况下,你不需要考虑自己管理内存,Swift会自动 ...

  9. Swift学习笔记十二

    方法 方法就是和某种特定类型相关联的函数.类.结构体.枚举都可以定义实例方法和类型方法.类型方法和OC中的类方法类似. 结构体和枚举也可以定义方法是Swift与C/OC之间很大的一个区别,在OC中,只 ...

随机推荐

  1. 平庸与卓越的差别 z

    本文是清华大学陈吉宁校长于在 2015 年第一次研究生毕业典礼暨学位授予仪式上的讲话,原文标题:选择与坚持.演讲非常精彩,值得您细细阅读. 亲爱的同学们: 今天,共有 1318 名同学获得博士.硕士学 ...

  2. Delphi MDI程序 父窗体如何调用当前活动子窗体的函数/过程

    一个MDI文本文件编辑器打开了N个子窗体子窗体的.pas文件有一些public的过程和函数我想在父窗体调用当前活动的子窗体函数我用Self.ActiveChildForm无法调用直接frmEdit.x ...

  3. Web前端开发工程师编程能力飞升之路

    [背景] 如果你是刚进入web前端研发领域,想试试这潭水有多深,看这篇文章吧:如果你是做了两三年web产品前端研发,迷茫找不着提高之路,看这篇文章吧:如果你是四五年的前端开发高手,没有难题能难得住你的 ...

  4. motan源码解读:注册中心zookeeper(2)

    上文大概讲解了利用zookeeper如何实现注册中心的.本文主要是从源码角度说明下.代码都在模块motan-registry-zookeeper中,其实在在这个模块中就3个类. ZkNodeType: ...

  5. 两个队列+k叉哈夫曼树 HDU 5884

    // 两个队列+k叉哈夫曼树 HDU 5884 // camp题解: // 题意:nn个有序序列的归并排序.每次可以选择不超过kk个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过TT, ...

  6. 从四大音乐APP首页设计对比分析产品方向

    原帖:http://www.ui.cn/detail/63201.html 本文章中作者例举四个音乐APP应用:虾米.网易.百度.QQ首页 1. 推荐内容:作者将四个首页界面划分出官方推荐与个性化推荐 ...

  7. Transact-SQL

    Transact-SQL(又称T-SQL),是在Microsoft SQL Server和Sybase SQL Server上的ANSI SQL实现,与Oracle的PL/SQL性质相近(不只是实现A ...

  8. Codeforces Educational Codeforces Round 15 E - Analysis of Pathes in Functional Graph

    E. Analysis of Pathes in Functional Graph time limit per test 2 seconds memory limit per test 512 me ...

  9. php 开发最好的ide: PhpStorm

    PhpStorm 跨平台. 对PHP支持refactor功能. 自动生成phpdoc的注释,非常方便进行大型编程. 内置支持Zencode. 生成类的继承关系图,如果有一个类,多次继承之后,可以通过这 ...

  10. UTC+0800是什么意思

    <%@ language="javascript" %> <html> <body> <% var d=new Date() var h= ...