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_once
behind the scenes to perform thread-safe lazy initialization of global variables and static properties.So the
static var
above 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_once
without 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_once
for 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_once
to 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.