需求
在某些時候,需要對請求進行延時處理挚冤。
例如:
- 對某條評論進行點贊,如果用戶無限點擊贊/取消贊按鈕赞庶,就會無限發(fā)出請求训挡。這是一種不合理的做法。通常采用一種折中的辦法尘执,在點擊按鈕一段時候(例如1秒)后才真正發(fā)出請求舍哄。
ScreenShot_20161110150104.png
例如:在切換不同Tab時候要調(diào)用不同的API
ScreenShot_20161110150508.png
解決方案
- 在UI層面,添加一個分類
/**
* @brief 在 delay秒之后誊锭,執(zhí)行action操作
*
* @param action 執(zhí)行的操作
* @param newObject 參數(shù)
* @param delay 延時時間
*/
-(void)debounceAction:(SEL)action object:(id)newObject delay:(NSTimeInterval)delay;
實現(xiàn)
+(void)debounceForTarget:(id)target action:(SEL)action object:(id)newObject delay:(NSTimeInterval)delay{
if(target == nil || action == nil){ return;}
// NSString *selectorString = NSStringFromSelector(action);
// id oldObj = objc_getAssociatedObject(target,[selectorString UTF8String]); // WRONG
id oldObj = objc_getAssociatedObject(target,action);
//NSLog(@"oldObj:%@",oldObj);
[NSObject cancelPreviousPerformRequestsWithTarget:target selector:action object:oldObj];
// Why do we need to retain this object???
objc_setAssociatedObject(target, action, newObject, OBJC_ASSOCIATION_RETAIN);
// NSString *selectorString2 = NSStringFromSelector(action);
// id newObj = objc_getAssociatedObject(target,[selectorString2 UTF8String]);
//id newObj = objc_getAssociatedObject(target,@selector(action));
//NSLog(@"newObj:%@",newObj);
[target performSelector:action withObject:newObject afterDelay:delay];
}
-(void)debounceAction:(SEL)action object:(id)newObject delay:(NSTimeInterval)delay{
[[self class] debounceForTarget:self action:action object:newObject delay:delay];
}
+(void)debounceForTarget:(id)target action:(SEL)action objectToBeCancelled:(id)oldObject objectToBePerform:(id)newObject delay:(NSTimeInterval)delay{
NSAssert(target != nil, @"target 不能為nil", nil);
// !!! call this method may cancel other actions ,
//[NSObject cancelPreviousPerformRequestsWithTarget:target];
[NSObject cancelPreviousPerformRequestsWithTarget:target selector:action object:oldObject];
// [NSObject cancelPreviousPerformRequestsWithTarget:target selector:action object:object];
// the Argument [object] may be different with last performrequest,if so,the last perform will not be cancelled.
[target performSelector:action withObject:newObject afterDelay:delay];
}
Demo
別人的git
NSObject-DebounceDemo.
- 在http request里增加time之類的想法表悬,改動便捷性都不合適。