search
LoginSignup
153

More than 5 years have passed since last update.

posted at

updated at

Swiftの @noescape をもっと使おう


(追記)
Swift 3 では @noescape の挙動がデフォルトになったため記述する必要がなくなりました。


よく知らなかったのですが、調べてみたら積極的に使っていこうという気になりました。

使用例

関数の引数で渡すクロージャにattributeとして付けます。

func action(@noescape closure: () -> ()) {
    closure()
}

(Appleのドキュメント)

@noescape を付けたクロージャに保証されること

  • クロージャはどこへも保持されない
  • クロージャは非同期的に後から実行されることはない

つまり、
クロージャの生存期間が関数よりも短い
ことを保証することになります。

よって、クロージャを渡した先で

  • クロージャをインスタンス変数などとして保持
  • クロージャを非同期的に後で実行

などする場合にはクロージャの生存期間が関数よりも延びてしまうので @noescape を付けることができません

(StackOverflowの回答)

いいこと

クロージャ内で self. を書かなくてよくなります。

more importantly disables the “self.” requirement in closure arguments.

(リリースノートより)

以下のような理由からではないかと思われます。

  • self. の記述はクロージャの生存が終わるまではselfが開放されないことを明示するためのもの(たぶん)
  • @noescape が付いたクロージャは生存がすぐに終わる
  • クロージャの生存が終わってもselfは必ず存在する
  • つまり、 self. を書いてselfが開放されないことを明示する必要がない

self. を書く必要がないということは [weak self][unowned self] について考える必要がない、つまり selfについての循環参照を考える必要がなくなる ということです!

@noescape なしの例

func action(closure: () -> ()) {
    closure()
}

class A {
    var count = 0
    func countAfterAction() {
        action {
            self.count++ // ここ
        }
    }
}

@noescape ありの例

func action(@noescape closure: () -> ()) {
    closure()
}

class A {
    var count = 0
    func countAfterAction() {
        action {
            count++ // ここ
        }
    }
}

またパフォーマンスが良くなる効果もあるようです。

This enables some minor performance optimizations

(リリースノートより)

結論

@noescape を付けられる場合は @noescape を付けていきたい。

  • クロージャ内で self. を書く必要がなくなる
  • つまり、selfの循環参照の問題を気にしなくてよくなる
  • パフォーマンスが良くなる

(おまけ) noescapeの意味

  • 生き延びない (escapeしない) という意味みたいです。

This indicates that the parameter is only ever called (or passed as an @noescape parameter in a call), which means that it cannot outlive the lifetime of the call.

(リリースノートより)

環境

Apple Swift version 2.1 (swiftlang-700.1.101.6 clang-700.1.76)
Target: x86_64-apple-darwin14.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
What you can do with signing up
153