當(dāng)遇到按鈕頻繁點(diǎn)擊猪瞬、或是某些監(jiān)聽(tīng)實(shí)時(shí)變化的方法時(shí)膀懈,往往只需要執(zhí)行最后一次方法的調(diào)用的場(chǎng)景。
比如彪置,如果用戶在2秒內(nèi)頻繁點(diǎn)擊按鈕拄踪,只需要執(zhí)行用戶最后一次點(diǎn)擊的操作蝇恶,也就是在2s內(nèi)的點(diǎn)擊事件都會(huì)被取消拳魁。
解決方法1.手動(dòng)實(shí)現(xiàn)NSTimer
創(chuàng)建NSTimer,記錄用戶兩次操作執(zhí)行的時(shí)間間隔撮弧,小于2秒潘懊,將NSTimer取消姚糊,重新開(kāi)始計(jì)算,在沒(méi)有新的點(diǎn)擊時(shí)授舟,2s后再執(zhí)行方法即可救恨。不推薦~
解決方法2.對(duì)當(dāng)前Run Loop中Selector Sources的取消
NSObject中的performSelector:withObject:afterDelay:方法將會(huì)在當(dāng)前線程的Run Loop中根據(jù)afterDelay參數(shù)創(chuàng)建一個(gè)Timer,如果沒(méi)有調(diào)用有inModes參數(shù)的方法释树,該Timer會(huì)運(yùn)行在當(dāng)前Run Loop的默認(rèn)模式中肠槽,也就是NSDefaultRunLoopMode定義的模式中。
performSelector:withObject:afterDelay:方法的使用看起來(lái)還是很簡(jiǎn)單的奢啥。這里講另外一個(gè)輔助函數(shù)秸仙,NSObject中靜態(tài)的cancelPreviousPerformRequestsWithTarget方法。該方法就是專門(mén)用來(lái)取消performSelector:withObject:afterDelay:方法所創(chuàng)建的Selector source(內(nèi)部上就是一個(gè)Run Loop的Timer source)桩盲。因此該方法和performSelector:withObject:afterDelay:方法一樣寂纪,只限于當(dāng)前Run Loop中。
我們可以利用cancelPreviousPerformRequestsWithTarget直接取消一個(gè)對(duì)象在當(dāng)前Run Loop中的所有未執(zhí)行的performSelector:withObject:afterDelay:方法所產(chǎn)生的Selector Sources赌结,如下代碼:
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)action:(UIButton *)button {
[self.class cancelPreviousPerformRequestsWithTarget:self selector:@selector(buttonAction) object:nil];
// 0.5秒后發(fā)起查詢
[self performSelector:@selector(buttonAction) withObject:nil afterDelay:0.5];
}
在0.5s內(nèi)的點(diǎn)擊捞蛋,實(shí)際上都被取消掉了。