只跑一次的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: &current, getCurrent: weakSelf?.current) {
        weakSelf?.viewModel.update(location: location)
    }
}

 

第一次使用@autoclosure,可以在caller端像參數一樣使用,但要小心getCurrent需使用weakSelf,可能有retain cycle 風險

 

current則放置在頁面的property 區域,以供下次拿來檢查是否太快

 

參考資料:

http://shoshino21.logdown.com/posts/732476-block-when-you-can-just-use-self-when-we-need-to-use-weakself-strongself

全站熱搜

小賢 發表在 痞客邦 留言(0) 人氣()