[译]Swift 3 中实现Dispatch once扩展

在3中原有的Dispatch once已经被废弃了。但是可以通过给DispatchQueue实现一个扩展方法来实现原有的功能。
代码如下:

public extension DispatchQueue {
    
    private static var _onceTracker = [String]()
    
    /**
     Executes a block of code, associated with a unique token, only once.  The code is thread safe and will
     only execute the code once even in the presence of multithreaded calls.
     
     - parameter token: A unique reverse DNS style name such as com.vectorform.<name> or a GUID
     - parameter block: Block to execute once
     */
    public class func once(token: String, block:()->Void) {
        objc_sync_enter(self)
        defer { objc_sync_exit(self) }
        
        if _onceTracker.contains(token) {
            return
        }
        
        _onceTracker.append(token)
        block()
    }
}

使用字符串token作为once的ID,执行once的时候加了一个锁,避免多线程下的token判断不准确的问题。
使用的时候可以传token

DispatchQueue.once(token: "com.vectorform.test") {
    print( "Do This Once!" )
}

或者使用UUID也可以:

private let _onceToken = NSUUID().uuidString

DispatchQueue.once(token: _onceToken) {
    print( "Do This Once!" )
}

欢迎关注我的微博:@没故事的卓同学

相关链接:
Dispatch once in Swift 3

推荐阅读更多精彩内容