Spec-Zone .ru
спецификации, руководства, описания, API

Библиотека разработчика XCode

Разработчик

Swift язык программирования

iBook
На этой странице

Deinitialization

deinitializer сразу вызывают, прежде чем экземпляр класса освобожден. Вы пишете deinitializers с deinit ключевое слово, подобное тому, как инициализаторы записаны с init ключевое слово. Deinitializers только доступны на типах классов.

Как работает Deinitialization

Swift автоматически освобождает Ваши экземпляры, когда они больше не необходимы, для высвобождения ресурсов. Swift обрабатывает управление памятью экземпляров посредством автоматического подсчета ссылок (ARC), как описано в Автоматическом Подсчете ссылок. Когда Ваши экземпляры освобождены, обычно Вы не должны выполнять ручную очистку. Однако, когда Вы работаете со своими собственными ресурсами, Вы, возможно, должны были бы выполнить некоторую дополнительную очистку сами. Например, при создании пользовательского класса, чтобы открыть файл и записать некоторые данные в него, Вы, возможно, должны были бы закрыть файл, прежде чем будет освобожден экземпляр класса.

Определения классов могут иметь самое большее один deinitializer на класс. deinitializer не берет параметров и записан без круглых скобок:

  • deinit {
  • // perform the deinitialization
  • }

Deinitializers вызывают автоматически, непосредственно перед тем, как освобождение экземпляра имеет место. Нельзя вызвать deinitializer самим. Суперкласс deinitializers наследован их подклассами, и суперкласс deinitializer вызывают автоматически в конце подкласса deinitializer реализацией. Даже если подкласс не обеспечивает свой собственный deinitializer, суперкласс deinitializers всегда вызывают.

Поскольку экземпляр не освобожден, пока его deinitializer не вызывают, deinitializer может получить доступ ко всем свойствам экземпляра, к этому обращаются и может изменить его поведение на основе тех свойств (таких как поиск имени файла, который должен быть закрыт).

Deinitializers в действии

Вот пример deinitializer в действии. Этот пример определяет два новых типа, Bank и Player, для простой игры. 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 возвращает меньшее число, чем число, которое требовали (и нуль возвратов, если никакие монеты не оставляют в банке). vendCoins(_:) объявляет numberOfCoinsToVend как переменный параметр, так, чтобы число могло быть изменено в организации метода без потребности объявить новую переменную. Это возвращает целочисленное значение для указания фактического числа монет, которые были предоставлены.

receiveCoins(_:) метод просто добавляет полученное число монет назад в хранилище монеты банка.

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 экземпляр инициализируется со стартовым допуском конкретного количества монет от банка во время инициализации, несмотря на то, что a Player если недостаточно монет доступно, экземпляр может принять меньше, чем то число.

Player класс определяет a winCoins(_:) метод, получающий определенное число монет от банка и добавляющий их к кошельку проигрывателя. Player класс также реализует deinitializer, который вызывают как раз перед a Player экземпляр освобожден. Здесь, deinitializer просто возвращает все монеты проигрывателя в банк:

  • var playerOne: Player? = Player(coins: 100)
  • 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 экземпляр создается с запросом на 100 монет, если они доступны. Это Player экземпляр сохранен в дополнительном Player переменную вызывают playerOne. Дополнительная переменная используется здесь, потому что проигрыватели могут оставить игру в любой точке. Дополнительное позволяет Вам отследить, существует ли в настоящее время проигрыватель в игре.

Поскольку playerOne дополнительное, это квалифицировано с восклицательным знаком (!) когда coinsInPurse к свойству получают доступ для печати его числа по умолчанию монет, и каждый раз, когда его winCoins(_:) метод вызывают:

  • 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"

Здесь, проигрыватель выиграл 2 000 монет. Кошелек проигрывателя теперь содержит 2 100 монет, и банк имеет только 7 900 монет в запасе.

  • 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"

Проигрыватель теперь оставил игру. Это обозначено путем установки дополнительного playerOne переменная к nil, значение “нет Player экземпляр”. В точке, что это происходит, playerOne ссылка переменной на Player экземпляр повреждается. Никакие другие свойства или переменные все еще не относятся к Player экземпляр, и таким образом, это освобождено для высвобождения его памяти. Непосредственно перед тем, как это происходит, ее deinitializer вызывают автоматически, и ее монеты возвращены в банк.