deinit
, так же как Вы задавали инициализаторы с ключевым словом init
. Деинициализаторы доступны только для типов-классов.
deinit {
// выполнить деинициализацию
}
Bank
и Player
, для простой игры. Класс Bank
управляет валютой, которой не может быть более 10,000 в обороте. Так как может быть только один банк в игре, то класс Bank
реализован в качестве класса со свойствами типа и методами для хранения и управления его текущим состоянием:
class Bank {
static var coinsInBank = 10_000
static func distribute(coins numberOfCoinsRequested: Int) -> Int {
let numberOfCoinsToVend = min(numberOfCoinsRequested, coinsInBank)
coinsInBank -= numberOfCoinsToVend
return numberOfCoinsToVend
}
static func receive(coins: Int) {
coinsInBank += coins
}
}
Bank отслеживает текущее количество монет, которые в нём хранятся, в его свойстве coinsInBank
. Он также предоставляет два метода distribute(coins:)
и receive(coins:)
для обработки распределения и сбора монет.
distribute(coins:)
проверяет, достаточно ли монет в банке перед их распределением. Если монет недостаточно, то Bank
возвращает меньшее число, чем то, что было запрошено (и возвращает нуль, если в банке нет монет). Он возвращает целое число для индикации того, сколько монет было предоставлено.
receive(coins:)
просто добавляет полученное число монет назад в банковское хранилище.
Player
описывает участника игра. Каждый игрок имеет определённое количество монет, хранимых ими в любой момент. Это представляется с помощью свойства coinsInPurse
:
class Player {
var coinsInPurse: Int
init(coins: Int) {
coinsInPurse = Bank.distribute(coins: coins)
}
func win(coins: Int) {
coinsInPurse += Bank.distribute(coins: coins)
}
deinit {
Bank.receive(coins: coinsInPurse)
}
}
Каждый объект типа Player
инициализируется стартовым значением определённого количества монет из банка в процессе инициализации, хотя объект Player
может получить и меньшее количество, если монет недостаточно.
Player
определяет метод win(coins:)
, который получает определённое количество монет из банка и прибавляет их к счёту игрока. Класс Player
также реализует деструктор, который вызывается прежде, чем объект Player
будет деаллоцирован. Здесь деструктор просто возвращает все монеты игрока в банк:
var playerOne: Player? = Player(coins: 100)
print("A new player has joined the game with \(playerOne!.coinsInPurse) coins")
// Выведет "A new player has joined the game with 100 coins"
print("There are now \(Bank.coinsInBank) coins left in the bank")
// Выведет "There are now 9900 coins left in the bank"
Новый экземпляр типа Player
создаётся с запросом на 100 монет, если они доступны. Объект Player
хранится в опциональной переменной Player
с названием playerOne
. Опциональная переменная используется ввиду того, что игроки могут покинуть игру в любой момент. Опционал позволяет Вам отслеживать, находится ли текущий игрок в игре.
playerOne
- это опционал, то он квалифицируется восклицательным знаком (!), когда производится доступ к его свойству coinsInPurse
для вывода его дефолтного значения монет или когда вызывается метод win(coins:)
:
playerOne!.win(coins: 2_000)
print("PlayerOne won 2000 coins & now has \(playerOne!.coinsInPurse) coins")
// Выводит "PlayerOne won 2000 coins & now has 2100 coins"
print("The bank now only has \(Bank.coinsInBank) coins left")
// Выводит "The bank now only has 7900 coins left"
playerOne = nil
print("PlayerOne has left the game")
// Выведет "PlayerOne has left the game"
print("The bank now has \(Bank.coinsInBank) coins")
// Выведет "The bank now has 10000 coins"
Игрок только что покинул игру. Это определяется присвоением nil
переменной playerOne
, что означает "нет объекта Player". В момент, когда это происходит, ссылка playerOne
на переменную Player
разбивается. Никакие другие свойства или переменные не ссылаются на этот объект, так что он деаллоциируется для высвобождения памяти. Прежде, чем это случится, автоматически будет вызван деинициализатор, а его монеты вернутся в банк.