Okay, so I found out about the new Swifty Dispatch API in Xcode 8. I'm having fun using DispatchQueue.main.async, and I've been browsing around the Dispatch module in Xcode to find all the new APIs.
But I also use dispatch_once to make sure that things like singleton creation and one-time setup don't get executed more than once (even in a multithreaded environment)... and dispatch_once is nowhere to be found in the new Dispatch module?
static var token: dispatch_once_t = 0
func whatDoYouHear() {
print("All of this has happened before, and all of it will happen again.")
dispatch_once(&token) {
print("Except this part.")
}
}
Since Swift 1.x, Swift has been using
dispatch_oncebehind the scenes to perform thread-safe lazy initialization of global variables and static properties.So the
static varabove was already usingdispatch_once, which makes it sort of weird (and possibly problematic to use it again as a token for anotherdispatch_once. In fact there's really no safe way to usedispatch_oncewithout this kind of recursion, so they got rid of it. Instead, just use the language features built on it:So that's all great if you've been using
dispatch_oncefor one-time initialization that results in some value -- you can just make that value the global variable or static property you're initializing.But what if you're using
dispatch_onceto do work that doesn't necessarily have a result? You can still do that with a global variable or static property: just make that variable's typeVoid:And if accessing a global variable or static property to perform one-time work just doesn't feel right to you -- say, you want your clients to call an "initialize me" function before they work with your library -- just wrap that access in a function:
See the migration guide for more.