vds_ios/VDS/Extensions/DispatchQueue+Once.swift

48 lines
1.3 KiB
Swift

//
// DispatchQueue+Once.swift
// VDS
//
// Created by Matt Bruce on 7/27/22.
//
import Foundation
extension DispatchQueue {
private static var _onceTracker = Set<String>()
public class func once(
file: String = #file,
function: String = #function,
line: Int = #line,
block: () -> Void
) {
let token = "\(file):\(function):\(line)"
once(token: token, block: block)
}
/**
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
) {
// Peek ahead to avoid the intersection.
guard !_onceTracker.contains(token) else { return }
objc_sync_enter(self)
defer { objc_sync_exit(self) }
// Double check we are the first in the critical section.
guard !_onceTracker.contains(token) else { return }
// Execute.
_onceTracker.insert(token)
block()
}
}