LoginSignup
9
5

More than 1 year has passed since last update.

【Swift】基礎的な部分だけど理解せずに使っていること

Posted at

はじめに

大変お世話になっているこちらの本Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語を読み返す度に「これちゃんと理解してなかった」という内容に出会うので、一度まとめてみました。
ありがたいことに、こちらで本の内容(一部?)が公開してありました。

あとは公式ドキュメントも参考に。

enum

- プロパティ

  • コンピューテッドプロパティ
  • スタティックプロパティ
    が使える
    var point = 100のようなストアドプロパティは使えない
enum Mahjong {
    case pon
    case chii
    case kan

    // コンピューテッドプロパティを定義
    var claim: String {
        switch self {
        case .pon: return "ポン"
        case .chii: return "チー"
        case .kan: return "カン"
        }
    }

    // スタティックプロパティを定義
    static let points = 25000
}

- メソッド

enumは、メソッドを定義することができる。
また、mutatingメソッドを使うことでenum自身を変更することができる。

enum Mahjong {
    case pon
    case chii
    case kan

    // メソッドを定義
    func claim() -> String {
        switch self {
        case .pon: return "ポン"
        case .chii: return "チー"
        case .kan: return "カン"
    }

    // mutating で変更可能
    mutating func update(mahjong: Mahjong) {
        self = mahjong
    }
}

- デフォルト値

enumに型を指定するとrawValueでデフォルト値が取得できる

enum Wind: Int {
    case east    // Wind.east.rawValue: 0
    case south   // Wind.south.rawValue: 1
    case west    // Wind.west.rawValue: 2
    case north   // Wind.north.rawValue: 3
}

enum Mahjong: String {
    case pon     // Mahjong.pon.rawValue: pon
    case chii    // Mahjong.pon.rawValue: chii
    case kan     // Mahjong.pon.rawValue: kan
}

Raw Valuecaseに値を代入することで定義できる

enum Wind: Int {
    case east = 10    // Wind.east.rawValue: 10
    case south = 20   // Wind.south.rawValue: 20
    case west = 30    // Wind.west.rawValue: 30
    case north = 40   // Wind.north.rawValue: 40
}

enum Mahjong: String {
    case pon = "ポン"   // Mahjong.pon.rawValue: ポン
    case chii = "チー"  // Mahjong.pon.rawValue: チー
    case kan = "カン"   // Mahjong.pon.rawValue: カン
}

- allCasesを使う

CaseIterableプロトコルに準拠させることで、ケースを配列で取得できる
caseはカンマでつなげて書いてもよい

enum Mahjong: CaseIterable {
  case pon, chii, kan
}
// Mahjong.allCases // [pon, chii, kan]

- Associated Valuesを使う

Associated Valuesを使うとcaseに付属的に関連する値をつけることができる

enum Mahjong {
    case score(east: Int, south: Int, west: Int, north: Int)

    func data() -> [Int] {
        switch self {
        case .score(let east, let south, let west, let north):
            return [east, south, west, north]
        }
    }
}

※全ての値がletorvarで一致している場合は
case let .score(east, south, west, north)と書ける。

Associated Type

Associated Typeを使用すると、1つの型に依存しない抽象的なプロトコルを定義することができ、具体的な型はプロトコルを準拠させるタイミングで指定させることができる。

protocol プロトコル {
  associated type 関連型

  var プロパティ名: 関連型
  func メソッド名(引数: 関連型)
}

プロトコルを準拠させる側では、typealiasを使って、具体的な型を指定する。

struct ProductItem: プロトコル {
  // String型で具体的な型を指定
  typealias 関連型 = String
  var プロパティ名 = "pon"
}

クロージャ

- escaping

escapingをつけることによって、クロージャが関数内部の変数をキャプチャし、関数外のスコープでも変数を保持し実行することができる。

具体的にはクロージャを非同期処理の後に実行したいときなど。
非同期処理を実行する多くの関数は、completionHandlerとしてクロージャ引数を取り、実行が完了するまでクロージャーは呼び出されないので、escapingして後で呼び出す必要がある。

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

escapingしない場合、クロージャは関数外のスコープで処理を実行できないため、例えばこうなる。

func someFunctionWithoutEscapingClosure(completionHandler: () -> Void) {
    completionHandlers()
}

- キャプチャとキャプチャリストとは

クロージャのキャプチャとは、クロージャが定義されたスコープに存在する変数や定数への参照を、クロージャ内のスコープでも保持することをいう。
デフォルトでは、このキャプチャはクラスのインスタンスへの強参照になるため、クロージャが解放されない限りキャプチャされたクラスのインスタンスが解放されない。

このような場合、キャプチャリストを用いることで弱参照を持つことができる。キャプチャを弱参照にすると、クロージャの解放状況に依存せずクラスのインスタンスの解放が行われる。また循環参照の解消にも役立つ。

キャプチャリストを定義するには、クロージャの引数の定義の前に[ ]を追加し、内部にweakキーワードもしくはunownedキーワードと変数名もしくは定数名の組み合わせを列挙する。

{ [ weak or unowned 変数名 or 定数名] (引数) -> 戻り値 in
    クロージャの呼び出し時に実行される文
}

weakunownedの違いはOptional型かどうかで、unownedを使い変数がnilの場合は実行時エラーが発生する

おわりに

Associated Typeはなんとなくでも使えてもないかも、、、enum[weak self]はよく使っていますが理解はできてなかったようで、まとめたことによりやっと理解できました。

今回の内容は、こちらの続き

でしたが、まだ分かっていないことがありそうなので、継続して読み返していきたいと思います。

参考

9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5