Swift でコードを 1 回だけ実行するにはどうすればよいですか? 質問する

Swift でコードを 1 回だけ実行するにはどうすればよいですか? 質問する

これまでに見た回答(123) は、GCD の使用をdispatch_once次のように推奨します。

var token: dispatch_once_t = 0
func test() {
    dispatch_once(&token) {
        print("This is printed only on the first call to test()")
    }
    print("This is printed for each call to test()")
}
test()

出力:

This is printed only on the first call to test()
This is printed for each call to test()

しかし、ちょっと待ってください。tokenは変数なので、次のように簡単に実行できます。

var token: dispatch_once_t = 0
func test() {
    dispatch_once(&token) {
        print("This is printed only on the first call to test()")
    }
    print("This is printed for each call to test()")
}
test()

token = 0

test()

出力:

This is printed only on the first call to test()
This is printed for each call to test()
This is printed only on the first call to test()
This is printed for each call to test()

したがってdispatch_once、 の値を変更できる場合、 は役に立ちませんtoken。また、 をtoken定数に変換することは、 型である必要があるため簡単ではありませんUnsafeMutablePointer<dispatch_once_t>

では、Swift を諦めるべきでしょうかdispatch_once? コードを 1 回だけ実行するより安全な方法はあるのでしょうか?

ベストアンサー1

ある男性が医者のところに行き、「先生、足を踏みつけると痛いんです」と言いました。医者は「だから、踏みつけるのをやめなさい」と答えました。

ディスパッチトークンを意図的に変更すれば、コードを2回実行することができます。しかし、複数回の実行を防ぐように設計されたロジックを回避すれば、どれでもそうすれば、それができるようになります。dispatch_onceこれは、単純なブール値ではカバーできない初期化や競合状態に関する (非常に) 複雑なコーナーケースをすべて処理するため、コードが 1 回だけ実行されるようにするための最良の方法です。

誰かが誤ってトークンをリセットしてしまうのではないかと心配な場合は、トークンをメソッドにラップして、その結果がどうなるかをできるだけ明確にすることができます。次のようなコードでは、トークンのスコープがメソッドに限定され、誰かが真剣に取り組まない限りトークンを変更できなくなります。

func willRunOnce() -> () {
    struct TokenContainer {
        static var token : dispatch_once_t = 0
    }

    dispatch_once(&TokenContainer.token) {
        print("This is printed only on the first call")
    }
}

おすすめ記事