Si l'utilisation de globaux initialisés paresseusement peut être judicieuse pour une initialisation ponctuelle, elle ne l'est pas pour d'autres types. L'utilisation de globaux initialisés paresseusement est très utile pour des choses comme les singletons, mais elle n'est pas très utile pour des choses comme la garde d'une configuration de swizzle.
Voici une implémentation de dispatch_once à la manière de Swift 3 :
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:@noescape(Void)->Void) {
objc_sync_enter(self); defer { objc_sync_exit(self) }
if _onceTracker.contains(token) {
return
}
_onceTracker.append(token)
block()
}
}
Voici un exemple d'utilisation :
DispatchQueue.once(token: "com.vectorform.test") {
print( "Do This Once!" )
}
ou en utilisant un UUID
private let _onceToken = NSUUID().uuidString
DispatchQueue.once(token: _onceToken) {
print( "Do This Once!" )
}
Comme nous sommes actuellement en période de transition de swift 2 à 3, voici un exemple de mise en œuvre de swift 2 :
public class Dispatch
{
private static var _onceTokenTracker = [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 token: String, @noescape block:dispatch_block_t) {
objc_sync_enter(self); defer { objc_sync_exit(self) }
if _onceTokenTracker.contains(token) {
return
}
_onceTokenTracker.append(token)
block()
}
}
0 votes
Duplicata possible : Pourquoi dispatch_once dans Swift 3 ?
0 votes
En fonction des réponses stackoverflow.com/a/38311178/1648724 y stackoverflow.com/a/39983813/1648724 J'ai donc créé un CocoaPod pour ce faire :
pod 'SwiftDispatchOnce', '~> 1.0'
Santé. :]