天天看点

析构—Swift学习笔记(十八)

注:本文为自己学习The Swift Programming Language的笔记,其中的例子为引用原书和其他博文或自己原创的。每个例子都会批注一些实践过程中的经验或思考总结。

1.基础

析构过程[deinitialization]由析构函数[deinitializer]完成,类的实例在被回收资源之前析构函数被调用,只有类才有析构函数。定义析构函数使用关键字deinit,格式和构造函数相同。

2.析构过程的完成

Swift自动回收不再使用的实例以释放资源,它通过自动引用计数[automatic reference counting,AFC]实现实例的内存管理。程序员不需要人工的实现实例回收,但是可以在回收之前完成一些有必要的工作:比如一个打开文件并访问文件的类在回收之前一定要关闭文件才行,这项工作可以交给析构函数来完成,它在类的实例在被回收资源之前被调用。

一个类最多能有一个析构函数,析构函数没有任何穿入参数也没有返回值:

deinit {
    // perform the deinitialization
}
           

析构函数是自动调用的,不能显式的调用它。子类继承超类的析构函数,子类的析构函数的实现完成之前自动调用超类析构函数,即使子类没有自己的析构函数超类的析构函数仍然在子类实例被回收时自动调用。

因为析构函数是在回收之前被调用的,它可以访问修改所有的属性并根据这些属性值做出相应工作。

3.析构过程的实现

通过一个例子来熟悉析构函数的使用,例子中包括了两个类型Bank和Player。Bank结构体管理一种流通量不超过10000的虚拟货币,因为只有一个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记录当前银行剩余货币,并有一个分配货币方法和收回货币方法,它们都是静态的。

Player类描述了游戏中的玩家,每个玩家钱包里有一些初始的货币,它可以从银行中赢取货币。Player类有一个析构函数,它实现了在Player实例被回收时将其持有货币收回银行,保证总的货币数保持10000:

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结构体的总货币数来理解析构过程:

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

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

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

/*
prints
    A new player has joined the game with 100 coins
    There are now 9900 coins left in the bank
    PlayerOne won 2000 coins & now has 2100 coins
    The bank now only has 7900 coins left
    PlayerOne has left the game
    The bank now has 10000 coins
*/
           

playerOne赋值nil时Swift自动回收之前的实例,调用Player类的析构函数把玩家剩余货币返还给银行。