154
151

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Swift その3Advent Calendar 2015

Day 4

Swiftの @noescape をもっと使おう

Last updated at Posted at 2015-12-03
(追記) 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
154
151
2

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
154
151

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?