一、封装一个once函数
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: (()->Void)) {
objc_sync_enter(self); defer { objc_sync_exit(self) }
if _onceTracker.contains(token) {
return
}
_onceTracker.append(token)
block()
}
}
二. 带立即执行闭包初始化器的全局变量
let dispatchOnce: () = {
print("dispatchOnce-------")
}()
/// 使用Aspects做交换: 用一个全局的常量来实现的dispatchOnce效果
let doSwizzles: () = {
print("doSwizzles----")
let oriSel1 = #selector(UIViewController.viewWillAppear(_:))
let wrappedBlock: @convention(block) (AspectInfo, Bool) -> Void = { aspectInfo, _ in
print("wrappedBlock---")
}
_ = try? UIViewController.aspect_hook(oriSel1, with: AspectOptions.positionBefore, usingBlock: wrappedBlock)
}()
// 之后在合适的时机使用变量,比如:
_ = dispatchOnce