我有一个搜索显示控制器,可以访问API端点。我当前的代码将在每个char上向API端点发出请求。我想要做的只是当用户停止输入500ms时才发出请求。
以下是代码:
注意: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
,但实际上这不起作用,因为每次用户输入一个字符时,搜索都会延迟,但它仍然会请求用户输入的每个字符。
我不想过度复杂,但我觉得它应该非常容易,而且我错过了一些东西。
答案 0 :(得分:1)
如何调用performSelector:withObject:afterDelay:?它可供所有NSObject使用,因此您可以从视图控制器中调用它。您唯一可能需要担心的是,不是每次事件都会发生,并排队等待2分钟的延迟:
- (void)performSelector:(SEL)aSelector
withObject:(id)anArgument
afterDelay:(NSTimeInterval)delay
示例(注意:为了演示,我编写了变量名称):
[self performSelector:@selector(callServer:) withObject:params afterDelay:0.5f];
<强>更新强>
似乎我的答案的第一部分是不够的。以下是一些可帮助您获得解决方案的新步骤:
1)创建一个NSTimer
属性,以便您可以在任何需要的地方访问
2)将searchDisplayController:shouldReloadTableForSearchString:
中的当前逻辑移动到新方法中,以便计时器可以将其用作选择器。例如:
- (void)callServerWithDictionary:(NSDictionary*)params;
3)每当调用searchDisplayController:shouldReloadTableForSearchString:
时,如果您的计时器实例为空,则将其实例化并将其时间间隔设置为500毫秒,并将其选择器设置为您在步骤1中创建的方法。如果计时器不为空,使其无效并将其设置为等于具有与之前相同的500ms间隔和选择器的新计时器实例。
4)如果您丢失了搜索字符串,则创建一个属性来保存它,并在每次调用searchDisplayController:shouldReloadTableForSearchString:
时更新它。虽然我相信您应该可以使用searchDisplayController.searchBar.text
。
答案 1 :(得分:0)
您可以使用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
});