如何在UISearchDisplayDelegate中执行操作之前设置延迟?
我有一个搜索显示控制器,它击中一个API端点。我当前的代码将向每个字符上的API端点发出请求。我想要做的只是当用户停止输入500毫秒时才发出请求。如何在UISearchDisplayDelegate中执行操作之前设置延迟?
下面是代码:
在UISearchDisplayDelegate
注:searchQueue是NSOperationQueue对象。
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self.searchQueue cancelAllOperations];
[self.searchQueue addOperationWithBlock:^(){
[self.AFRequestManager.operationQueue cancelAllOperations];
NSString *access_token = [[FBSDKAccessToken currentAccessToken] tokenString];
NSDictionary *params = @{@"name": searchString, @"access_token": access_token };
NSString *getUrl = [baseUrl stringByAppendingString:@"api/users/search"];
[self.AFRequestManager GET:getUrl parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.searchedUsers = responseObject;
[self.searchDisplayController.searchResultsTableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
}];
return NO;
}
此委托方法被调用为每一个字符,用户在键入的,我想等到用户完成指定名称。
我试过使用NSTimer
,但它很混乱。我绝对可以将searchString传递给userInfo。但是,一旦我使NSTimer无效,就不能再使用它。
我尝试过使用dispatch_after
,但实际上这并不起作用,因为每次用户输入字符时,搜索都会延迟,但它仍在为用户输入的每个字符发出请求。
我不想过度复杂,但我觉得它应该是超级简单,我错过了一些东西。
怎么样调用performSelector:withObject:afterDelay:?它可用于所有NSObject,因此您可以从视图控制器调用它。
- (void)performSelector:(SEL)aSelector
withObject:(id)anArgument
afterDelay:(NSTimeInterval)delay
例子(注:我做了变量名称为示范的目的):
你可能会担心没有采取在每一个事件和排队值得延迟2分钟的唯一的事情[self performSelector:@selector(callServer:) withObject:params afterDelay:0.5f];
UPDATE:
看来好像我的回答的第一部分是不够的。这里有一些新的步骤,将帮助你得出一个解决方案:
1)创建一个NSTimer
属性,这样你需要的地方
2,你可以访问它)移动当前的逻辑searchDisplayController:shouldReloadTableForSearchString:
到一个新的方法,以便您的计时器可以将其用作其选择器。例如:
- (void)callServerWithDictionary:(NSDictionary*)params;
3)每当searchDisplayController:shouldReloadTableForSearchString:
被调用,如果你的计时器实例为null,实例并设置其时间间隔为500毫秒,其选择是你在步骤1.如果创建的方法定时器不为空,使其无效,并将其设置为等于具有与之前相同的500ms间隔和选择器的新定时器实例。
4)如果丢失搜索字符串,则创建一个属性来保存它,并在每次调用searchDisplayController:shouldReloadTableForSearchString:
时更新它。虽然我相信你应该可以用searchDisplayController.searchBar.text
之类的东西来访问它。
您可以使用GCD dispatch_after。这里是一些例子。
double delayInSeconds = 3.0;
dispatch_time_t buyTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(buyTime, dispatch_get_main_queue(), ^(void)
{
//code that will be executed after delay
}
您可以使用此
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(10, queue, ^(size_t index) {
// block will be executed 10 times
// number of launch passes to block
});
您可以使用用户信息中的NSTimer到搜索字符串传递到选择,或使用dispatch_after,创建一个新的请求,当用户键入一个字母和取消任何延迟请求。无论哪种方式,请求都是堆叠的,需要在某个时候取消。 – Thomas 2015-03-30 19:10:16
我确实尝试过dispatch_after,但仍然会排队3个延迟500ms的请求。我只想要1个请求,除非用户不输入500ms的字符。 – okysabeni 2015-03-30 20:17:55