当前位置:  开发笔记 > IOS > 正文

如何在Swift中执行一次代码只执行一次?

如何解决《如何在Swift中执行一次代码只执行一次?》经验,为你挑选了2个好方法。

到目前为止,我已经看到了这些问题的答案(1,2,3)建议使用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_onceSwift吗?有一种更安全的方式只执行一次代码吗?



1> Adam Wright..:

一名男子去看医生,然后说:"医生,当我踩到我的脚上时会疼." 医生回答说:"别这样做".

如果您故意改变您的调度令牌,那么是 - 您将能够执行两次代码.但是如果你解决了旨在以任何方式阻止多次执行的逻辑,你就能够做到.dispatch_once仍然是确保代码只执行一次的最佳方法,因为它处理初始化和竞争条件下的所有(非常)复杂的极端情况,简单的布尔值不会覆盖.

如果您担心某人可能会意外地重置令牌,您可以将其包装在一个方法中并使其显而易见,因为它可能是后果.像下面这样的东西会将令牌范围扩展到方法,并阻止任何人在没有认真努力的情况下更改它:

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

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


单独的第一线可能就是你所需要的.其余的答案是多余的.;)

2> Jeremy W. Sh..:

由闭包初始化的静态属性是懒惰运行的,最多只运行一次,所以这只打印一次,尽管被调用了两次:

/*
run like:

    swift once.swift
    swift once.swift run

to see both cases
*/
class Once {
    static let run: Void = {
        print("Behold! \(__FUNCTION__) runs!")
        return ()
    }()
}

if Process.arguments.indexOf("run") != nil {
    let _ = Once.run
    let _ = Once.run
    print("Called twice, but only printed \"Behold\" once, as desired.")
} else {
    print("Note how it's run lazily, so you won't see the \"Behold\" text now.")
}

示例运行:

~/W/WhenDoesStaticDefaultRun> swift once.swift
Note how it's run lazily, so you won't see the "Behold" text now.
~/W/WhenDoesStaticDefaultRun> swift once.swift run
Behold! Once runs!
Called twice, but only printed "Behold" once, as desired.


您不需要在类型中包装静态属性.您可以声明一个全局变量或常量,并使用闭包进行初始化.关闭将被懒惰地称为一次.例外情况是,如果在main.swift中定义了全局变量/常量,它仍然会按照定义(即不是懒惰)执行一次.
顺便说一句,这实际上是在生成的代码中使用'dispatch_once':)。它只是将其隐藏在语言语义中。
推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有