LoginSignup
30

More than 5 years have passed since last update.

Wantedly Swift社内勉強会(weak, unowned, パターンマッチ)

Posted at

目次

  • weak reference(弱参照)とunowned reference(非所有参照)
  • @noescape
  • パターンマッチ

weak referenceとunowned reference

weak reference(弱参照)

  • リファレンスカウンタの値を上げない
  • 参照していた対象のインスタンスが不要になり、解放されると弱い参照の変数には自動的にnilが代入される
  • 定数ではなく、変数に使わなければならない
  • 型は、オプショナル型である必要がある

unowned reference(非所有参照)

  • リファレンスカウンタの値を上げない
  • 弱参照との違いは、「nilを値とはしない」こと
  • 参照の対象が解放されても、自動的にnilを代入するということはない
  • 型にオプショナルを指定することはできない
  • Appleのドキュメントでは、変数の値がnilにならないことが明らかな場合、unownedを使うことが推奨されている
  • しかし、「本当にunownedでいいのか?」というチェックコストを考えると、weakで良い気がする

@noescape

  • 関数の引数がクロージャの時に、引数の属性としてクロージャの離脱がないことを明示することができる
func setFunc(@noescape f: (Int) -> Int) {

}

のように使用する。

  • クロージャ内でselfを書かなくて良くなる
  • 循環参照について考慮しなくてよくなる
  • filtermapなどで使われている
  • より、unowned使う事あんの?という気持ちになりました。

パターンマッチ

タプル

switch文


switch day {
case (1, 1...5):
    print("正月休み")
case (4, 29), (5, 2...6):
    print("連休")
case (8, let d):
    print("8月\(d)日は夏休み")
case (10, _):
    print("10月です")
case (_, 13) where week() == "金曜日":
    print("13日の金曜日")
case let (month, day) where day > 15:
    print("\(month)\(day)日は後半戦です")
}

Optional型をつかう


typealias People = (String, Int?)

switch p {
case let (name, age?) where age >= 18:
    print("\(name)は免許を取れるよ")
case let (name, (15...18)?):    
    print("\(name)は高校生だね。")
case (let name, nil):
    print("年齢不明")
}

列挙型

共用型

  • 列挙型とタプルの構造を併せ持つことができる型
  • 下記のように宣言する

enum Ticket {
    case Normal(Int, Bool, Bool) //(価格、子供かどうか、回数券かどうか)
    case Card(Int, Bool) //(残高、子供かどうか)
    case AgedCard //敬老カード
}

switch文


switch t {
case let .Normal(fare, isChild, _):
    print("普通券:\(isChild ? "子供" : "大人")料金 \(fare)円")
case .AgedCard:
    print("敬老カード")
case .Card(let r, true) where r < 110:
    print("カード(子供): 残高不足")
case .Card(let r, false) where r < 230:
    print("カード(大人): 残高不足")
case .Card:
    print("カード")
}

if-case文


if case .Card(let r, true) = t where r < 110 {
    print("カード(子供): 残高不足")
}

  • optionalに対して

if let t = ticket, case .Normal(220, _, _) = t {
    print("220円券")
}

上記と下記は同じ意味


if case .Normal(220, _, _)? = ticket {
    print("220円券")
}

  • 複数ケースをカンマでつなげることもできる

for-in文


for case  let .Normal(fare, isChild, isCoupon) in tickets where fare > 220 {
    //Some
}

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
30