Swift 里的 dispatch_once 替代方案

Sep 27, 2020 • 预计阅读时间 1 分钟

ObjC 里的 dispatch_once 使用起来很方便,但是 Swift 里废弃使用这个方法了,原因是鼓励大家使用 static let

Objective-C

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    YogaSwizzleInstanceMethod(self, @selector(initWithFrame:), @selector(_yoga_initWithFrame:));
    ogaSwizzleInstanceMethod(self, @selector(setFrame:), @selector(_yoga_setFrame:));
    YogaSwizzleInstanceMethod(self, @selector(setBounds:), @selector(_yoga_setBounds:));
#if TARGET_OS_OSX
    YogaSwizzleInstanceMethod(self, @selector(setFrameSize:), @selector(_yoga_setFrameSize:));
    YogaSwizzleInstanceMethod(self, @selector(setBoundsSize:), @selector(_yoga_setBoundsSize:));
#endif
}); 

Swift

struct once {
    static let token = { () -> Bool in
        YogaSwizzleInstanceMethod(UIView.self, #selector(UIView.init(frame:)), #selector(_swift_yoga_init(frame:)))
        YogaSwizzleInstanceMethod(UIView.self, #selector(setter: UIView.frame), #selector(_swift_yoga_set(frame:)))
        YogaSwizzleInstanceMethod(UIView.self, #selector(setter: UIView.bounds), #selector(_swift_yoga_set(bounds:)))
        #if os(macOS)
        YogaSwizzleInstanceMethod(NSView.self, #selector(NSView.setFrameSize(_:)), #selector(_swift_yoga_set(frameSize:)))
        YogaSwizzleInstanceMethod(NSView.self, #selector(NSView.setBoundsSize(_:)), #selector(_swift_yoga_set(boundsSize:)))
        #endif

        return true
    }()
}

_ = once.token

token 是什么类型都可以,只是需要有个返回值能让编译通过,返回值也是没有用的。

Swift
版权声明:如果转发请带上本文链接和注明来源。

lvv.me

iOS/macOS Developer

恢复 Xcode 默认设置

拉取 Github 上的 Pull Request 代码到本地分支