Dispatch once in Swift 3
Old Version
在Swift2.3中,为保证一段代码只被执行一次,可以利用dispatch_once
如下代码:
1 2 3 4 5
| var onceToken:dispatch_once_t = 0 func dosomeThing() { dispatch_once(&onceToken){ } }
|
此方法经常用于单利的创建等等,但是在Swift3.0中已被弃用,这里提供两个类似于dispatch_once的功能实现方式
方法一
New
因为此方法已经被弃用,所以可以利用分类来实现类似于dispatch_once的功能,如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public extension DispatchQueue { public static var _onceTracker = [String]() public class func once(token: String, block:(Void)->Void) { objc_sync_enter(self) defer { objc_sync_exit(self) } if _onceTracker.contains(token) { return } _onceTracker.append(token) block() } }
|
此时我们调用此方法只需要
1 2 3
| DispatchQueue.once(token: "com.gybar.new") { (_) in //doSomeThing }
|
进一步精简化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public extension DispatchQueue { public static var _onceTracker = [String]() public class func once(file: String = #file, function: String = #function, line: Int = #line, block:(Void)->Void) { let token = file + ":" + function + ":" + String(line) once(token: token, block: block) } public class func once(token: String, block:(Void)->Void) { objc_sync_enter(self) defer { objc_sync_exit(self) } if _onceTracker.contains(token) { return } _onceTracker.append(token) block() } }
|
就可以实现类似于dispatch_once的功能
方法二
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Object { static let sharedInstance = Object() } // Global constant. let constant = Object() // Global variable. var variable: Object = { let variable = Object() variable.doSomething() return variable }()
|
参考