\
2014年08月31日
Posted by 屋台ブルー at 2014年08月31日00:00 Comment(0)

Swiftで遊ぼう! - 52 デ・イニシャライザー? なぜ動かない?

swift_logo2014年9月2日追加:Xcode6β6のplaygroundsではデイニシャライザーのテストはうまくできない→「Swiftで遊ぼう! - 54 ARCの問題解決?
ARCの勉強の前に、もう一つ勉強し忘れていた項目があった。デ・イニシャライザーだ。クラスはイニシャライズーによって初期化されるとメモリーは割りふられ、必要なくなると勝手にARCが働いてメモリーは解放されるそうですが、開放されない状況もあり、マニュアルでメモリーを解放する方法が用意されている。それがデイニシャライザーだ。

し・か・し! このデイニシャライザー、動かないんです。考えても理由が分からない!

ストラクチャー型のBankですが、プロパティは「static」付きで宣言されている。staticって、グローバルに使える定数、変数、関数などを生み出すことができるんですよね。その場合、staticを使ったその行に具体的な「値」の代入←初期化?をしないといけないようです。それから、static変数があると、インスタンス生成はなくなる。宣言そのものがグローバルな働きをするってことになるから、複数のインスタンスを持つと変です。ゲームで使うストラクチャ型のBankは当然、1つだけで十分、プレーヤーが何人でもBankは1つということで、staticを宣言ということでしょう。staticの使い方の1つですね。

struct Bank {
static var coinsInBank = 10_000
さて、グローバルに使える変数「coinsInBank」を宣言しているが、この場合、必ずここで初期化をしなきゃいけないみたいです。←本当でしょうか?
例えば、次のイニシャライズステップに組み込んで初期化できるのか実験してみましたができませんでした。
static var coinsInBank: Int
init() {
coinsInBank = 10_000
}
上記はエラーになりますよ。グローバルな値なので、インスタンス生成時に働くイニシャライザーの出番が無いですよね。無いということは、イニシャライズされないのでエラーになるんでしょうか?

static func vendCoins(var numberOfCoinsToVend: Int) -> Int {
numberOfCoinsToVend = min(numberOfCoinsToVend, coinsInBank)
coinsInBank -= numberOfCoinsToVend
return numberOfCoinsToVend
}
実は関数「vendCoins」も少し理解するのに時間がかかった。どうしてかというと、「min(A,B)」というメソッド?が教科書に載ってなかったからです。同じタイプの数字を2つ比べて小さい方を返すメソッドなんですが、じゃあminの逆で大きい方を返すのは「max」? 
この関数は、金額を指定して銀行から借りるメソッドです。指定した金額が銀行にあれば(coinsInBankの数が大きければ)、そのお金がそのまま手に入れられるが、銀行のお金が少なければ、銀行に残っている残金をすべて手に入れます。
static func receiveCoins(coins: Int) {
coinsInBank += coins
}
この関数は銀行に返す関数で、銀行の残金額が増えます。
}

構造体のBankはシンプルです。残金(coinsInBank)と借りる時に使う関数(vendCoins)と返す関数(receiveCoins)の3つのプロパティだけで、すべてグローバルなstatic変通と関数だ。

そして、次に人数不定のプレーヤーはクラス宣言となるが、構造体と似ていて、財布にある金(coinsInPuuse)と銀行から借りる時に使う関数「withCoins」の2つのプロパティが組み込まれていますね。ここで新しいのは、クラスが消滅した時のステップ、デイニシャライザがあって持っていたコインを全て銀行に返すステップだ。

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

このプレーヤはクラスなんで、必ずインスタンスを生成しないと使えないため以下のインスタンス宣言をする。
var playerOne: Player? = Player(coins: 100)
println("A new player ha joined the game with \(playerOne!.coinsInPurse) coins")
println("There are now \(Bank.coinsInBank) coins in the Bank")

//A new player ha joined the game with 100 coins
//There are now 9900 coins in the Bank

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

//PlayerOne won 2000 coins & now has 2100
//The bank now only has 7900 coins

とここまでは思い通りに動いている。
じゃあ、デイニシャライザーということで、次のステップに進むと...

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

//PlayerOne has left the game
//The bank now has 7900 coins

お金が銀行に戻っていない(T_T)


同じカテゴリー(Swiftで遊ぼう!)の記事画像
Swiftで遊ぼう! - プログラミングまとめ(ときどき更新)
Swiftで遊ぼう! - 番外編 - Xcode6:ショートカットと用語説明
Swiftで遊ぼう! - 209 - ルートビューのコードは続く:CGRect
Swiftで遊ぼう! - 208 - ルートビューのコード
Swiftで遊ぼう! - 207 - ツールバーボタンとビューコントローラーを繋ぐ
Swiftで遊ぼう! - 206 - ビューコントローラーにビューコントローラーを載せる
同じカテゴリー(Swiftで遊ぼう!)の記事
 Swiftで遊ぼう! - プログラミングまとめ(ときどき更新) (2021-01-31 00:00)
 Swiftで遊ぼう! - 番外編 - Xcode6:ショートカットと用語説明 (2015-04-05 00:00)
 Swiftで遊ぼう! - 209 - ルートビューのコードは続く:CGRect (2015-02-06 00:00)
 Swiftで遊ぼう! - 208 - ルートビューのコード (2015-02-05 00:00)
 Swiftで遊ぼう! - 207 - ツールバーボタンとビューコントローラーを繋ぐ (2015-02-04 00:00)
 Swiftで遊ぼう! - 206 - ビューコントローラーにビューコントローラーを載せる (2015-02-03 00:00)

上の画像に書かれている文字を入力して下さい
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。

削除
Swiftで遊ぼう! - 52 デ・イニシャライザー? なぜ動かない?
    コメント(0)