performSelector配合cancelPreviousPerformRequestsWithTarget真是妙用無窮,有如檳榔加煙的功效。
倆API長這樣:(不認(rèn)識的童鞋建議轉(zhuǎn)行哈,建議賣黃燜雞。)
-(void)performSelector:(SEL)aSelector
withObject:(nullable id)anArgument
afterDelay:(NSTimeInterval)delay
- (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget
selector:(SEL)aSelector
object:(nullable id)anArgument;
1、需求背景:比如直播間支持讓用戶一直點贊,總不能用戶點一次贊我們代碼調(diào)一次接口,在并發(fā)100W的直播很可能被用戶點掛掉。所以產(chǎn)品要求每隔3秒上傳一次3秒內(nèi)的累計點贊數(shù)。
實現(xiàn)方法很多,NSTimer,GCD的After什么的都可以,這里說用
performSelector配合cancelPreviousPerformRequestsWithTarget來簡單實現(xiàn):
模擬點擊事件代碼:
UIButton * button = [UIButton buttonWithType:0];
button.frame = CGRectMake(100, 180, 100, 100);
button.backgroundColor = [UIColor orangeColor];
[self.view addSubview:button];
[button addTarget:self action:@selector(buttonClickTwo) forControlEvents:1<<6];
- (void)buttonClickTwo{
[self performSelector:@selector(sayHelloTwo) withObject:nil afterDelay:3];
}
- (void)sayHelloTwo{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(sayHelloTwo) object:nil];
NSLog(@"hello");//這里寫上傳點贊代碼
}
剛開始sayHelloTwo先調(diào)用,cancelPreviousPerformRequestsWithTarget 調(diào)用的時候sayHelloTwo已經(jīng)調(diào)用了,之后cancelPreviousPerform會取消3秒內(nèi)的request ,結(jié)果就是hello 會每隔3秒打印一次,達到需求要求說明實現(xiàn)木有問題。
2、需求背景:比如直播主頁也支持讓用戶一直點贊,也不能用戶點一次贊我們代碼調(diào)一次接口,因為沒必要,這里不要求數(shù)據(jù)那么及時。所以要求用戶點贊結(jié)束之后再調(diào)接口上傳給服務(wù)器。
那么問題來了,怎么算結(jié)束?基本可以認(rèn)為用戶點贊0.5秒之后沒再繼續(xù)點,就算結(jié)束。當(dāng)然0.5可以商議,舉個栗子而已。
模擬點擊事件代碼:
UIButton * button = [UIButton buttonWithType:0];
button.frame = CGRectMake(100, 180, 100, 100);
button.backgroundColor = [UIColor orangeColor];
[self.view addSubview:button];
[button addTarget:self action:@selector(buttonClick) forControlEvents:1<<6];
- (void)buttonClick{
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(sayHello) object:nil];
[self performSelector:@selector(sayHello) withObject:nil afterDelay:0.5];
}
- (void)sayHello{
NSLog(@"hello");//這里寫上傳點贊代碼
}
可以看到,每次延遲調(diào)用sayHello之前都取消前一個還沒調(diào)的request。結(jié)果就是只要每次點贊操作間隔在0.5秒之內(nèi),都算連續(xù)的。間隔超過0.5秒將算結(jié)束,將調(diào)用sayHello。
cancelPreviousPerformRequestsWithTarget 寫在了不同的位置,產(chǎn)生完全不同的結(jié)果。
ps:有滾動事件時得注意performSelector的mode問題。