Swift-防止函数被调用两次

Swift-防止函数被调用两次,swift,Swift,我的主要代码太长,无法放在这里,因此我将尝试用更简单的解释。假设我有一个名为“count”的全局变量,它被函数使用。如果count因w.e原因被调用两次,如下面的代码所示。。。我怎样才能使输出为“10,10”而不是“10,20” 将DispatchQueue与静态令牌一起使用(通过应用程序生命周期缓存),下面是一个有用的扩展: extension DispatchQueue { private static var tokens: [String] = [] // static, so

我的主要代码太长,无法放在这里,因此我将尝试用更简单的解释。假设我有一个名为“count”的全局变量,它被函数使用。如果count因w.e原因被调用两次,如下面的代码所示。。。我怎样才能使输出为“10,10”而不是“10,20”


将DispatchQueue与静态令牌一起使用(通过应用程序生命周期缓存),下面是一个有用的扩展:

extension DispatchQueue {

    private static var tokens: [String] = [] // static, so tokens are cached

    class func once(executionToken: String, _ closure: () -> Void) {
        // objc_sync_enter/objc_sync_exit is a locking mechanism
        objc_sync_enter(self)
        defer { objc_sync_exit(self) }
        // if we previously stored token then do nothing
        if tokens.contains(executionToken) { return }
        tokens.append(executionToken)
        closure()
    }
}

func doSomething() {
    DispatchQueue.once(executionToken: "doSomething") {
        print("This should be executed once")
    }
}

doSomething()
doSomething()
doSomething()
“此操作应执行一次”将仅打印一次

您还可以使用惰性机制:

class SomeClass {
    lazy var executeOnce: () -> Void = {
        doSomething()
        return {}
    }()

    func doSomething() {
        print("This should be executed once")
    }
}

let someClass = SomeClass()
someClass.executeOnce()
someClass.executeOnce()
someClass.executeOnce()

它是线程安全的开箱即用,因此您无需担心锁定问题。

使用带有静态令牌的DispatchQueue(通过应用程序生命周期缓存),下面是一个有用的扩展:

extension DispatchQueue {

    private static var tokens: [String] = [] // static, so tokens are cached

    class func once(executionToken: String, _ closure: () -> Void) {
        // objc_sync_enter/objc_sync_exit is a locking mechanism
        objc_sync_enter(self)
        defer { objc_sync_exit(self) }
        // if we previously stored token then do nothing
        if tokens.contains(executionToken) { return }
        tokens.append(executionToken)
        closure()
    }
}

func doSomething() {
    DispatchQueue.once(executionToken: "doSomething") {
        print("This should be executed once")
    }
}

doSomething()
doSomething()
doSomething()
“此操作应执行一次”将仅打印一次

您还可以使用惰性机制:

class SomeClass {
    lazy var executeOnce: () -> Void = {
        doSomething()
        return {}
    }()

    func doSomething() {
        print("This should be executed once")
    }
}

let someClass = SomeClass()
someClass.executeOnce()
someClass.executeOnce()
someClass.executeOnce()
它是线程安全的开箱即用,因此您无需担心锁定问题。

更改

func helloWorld(){
var counter = 0
for i in 1...10{
    count = count + 1
    counter = counter + 1
}
print(count)
}

这样,您可以在更改之前将计数值存储到计数器中,然后使其再次等于上一个计数值

注意:这样,无论调用函数多长时间,调用helloWorld()时都会得到10

您可以按如下所示更改功能:

func helloWorld(_ countValue: Int){
var counter = self.count
for i in 1..<countValue{
    count = count + 1
}
print(count)
self.count = counter
建议:使用更改外部值的函数不是一个好做法

改变

func helloWorld(){
var counter = 0
for i in 1...10{
    count = count + 1
    counter = counter + 1
}
print(count)
}

这样,您可以在更改之前将计数值存储到计数器中,然后使其再次等于上一个计数值

注意:这样,无论调用函数多长时间,调用helloWorld()时都会得到10

您可以按如下所示更改功能:

func helloWorld(_ countValue: Int){
var counter = self.count
for i in 1..<countValue{
    count = count + 1
}
print(count)
self.count = counter
建议:使用更改外部值的函数不是一个好做法


我正试图在我的主代码中实现lazy选项。它在应用程序初始化时工作,但在我离开视图控制器并返回页面时工作。我的executeOnce函数甚至没有被调用。这可能是因为我的视图控制器也被实例化为“Lazy”,我正试图在我的主代码中实现Lazy选项。它在应用程序初始化时工作,但在我离开视图控制器并返回页面时工作。我的executeOnce函数甚至没有被调用。这可能是因为我的视图控制器也被实例化为“Lazy”。