只跑一次的Globa function: /// Run once after delay if no be called /// /// - Parameters: /// - delay: delay time /// - saveCurrent: should put it to 'property scope' /// - getCurrent: should pass 'weak' self property /// - once: do once closure func runOnce(delay: TimeInterval, saveCurrent: inout DispatchTime?, getCurrent: @autoclosure @escaping () -> DispatchTime?, once: @escaping () -> Void) { let begin: DispatchTime = DispatchTime.now() saveCurrent = begin DispatchQueue.main.asyncAfter(deadline: begin + delay) { guard let current = getCurrent(), current == begin else { print("Ignore because still be called") return } print("Run once") once() } }
Caller端用法:
private var current: DispatchTime? func test() { weak var weakSelf = self runOnce(delay: 3, saveCurrent: ¤t, getCurrent: weakSelf?.current) { weakSelf?.viewModel.update(location: location) } }
第一次使用@autoclosure,可以在caller端像參數一樣使用,但要小心getCurrent需使用weakSelf,可能有retain cycle 風險
current則放置在頁面的property 區域,以供下次拿來檢查是否太快
參考資料:
全站熱搜
留言列表