ReactiveCocoa:油门从不执行/不工作
ReactiveCocoa: throttle never executes / not working
我尝试订阅一个带油门的信号,但它从未执行过。
我有一个 UISearchController (注意:来自 iOS8 的 UISearchController,而不是较旧的 UISearchDisplayController,它工作起来更安静,并且在网络上有数以千计的工作教程和示例) 并希望在用户键入时发出 API-请求。
为了降低流量,我不想开始 API-请求用户按下的每个键,但是当用户停止一段时间时,比如在最后一次按键后 500 毫秒。
由于我们无法在 UISearchController 的 SearchBar 中引用 TextField,我们使用 UISearchController 的委托:
要获取搜索栏中文本字段的最新键入文本,我使用此方法:
#pragma mark - UISearchResultsUpdating
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchText = searchController.searchBar.text;
// strip out all the leading and trailing spaces
NSString *strippedString = [searchText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if([strippedString isEqualToString:self.currentFilter]) {
return;
}
self.currentFilter = strippedString;
}
属性 currentFilter 保留当前搜索字符串。
此外,我在 currentFilter-属性 上有一个 RACObserve,以对对此 属性 所做的每个更改做出反应:
[RACObserve(self, currentFilter) subscribeNext:^(NSString* x) {
NSLog(@"Current Filter: %@", x);
// do api calls and everything else
}];
现在我想抑制这个信号。但是当我执行节流调用时,什么也没有发生。永远不会调用 SubscribeNext:
[[RACObserve(self, currentFilter) throttle:500] subscribeNext:^(NSString* x) {
NSLog(@"%@", x); // will never be called
}];
如何实现限制搜索栏中的输入?这里有什么问题?
更新
感谢@malcomhall,我找到了 workaround besides ReactiveCocoa。我将 updateSearchResultsForSearchController-delegate 方法中的代码移动到一个单独的方法中,并使用 performSelector 对其进行调度,并使用 cancelPreviousPerformRequestsWithTarget 取消此调度程序。
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(useTextSearchQuery) object:nil];
[self performSelector:@selector(useTextSearchQuery) withObject:nil afterDelay:1.0];
}
无论如何,我仍然想了解 ReactiveCocoa 的 "throttle" 是如何工作的,为什么不在这种情况下:)
-throttle:
接受 NSTimeInterval
,这是 秒 的浮点规范,而不是毫秒。
鉴于问题中的代码,我希望您会在 500 秒后看到结果。
我尝试订阅一个带油门的信号,但它从未执行过。
我有一个 UISearchController (注意:来自 iOS8 的 UISearchController,而不是较旧的 UISearchDisplayController,它工作起来更安静,并且在网络上有数以千计的工作教程和示例) 并希望在用户键入时发出 API-请求。 为了降低流量,我不想开始 API-请求用户按下的每个键,但是当用户停止一段时间时,比如在最后一次按键后 500 毫秒。
由于我们无法在 UISearchController 的 SearchBar 中引用 TextField,我们使用 UISearchController 的委托:
要获取搜索栏中文本字段的最新键入文本,我使用此方法:
#pragma mark - UISearchResultsUpdating
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchText = searchController.searchBar.text;
// strip out all the leading and trailing spaces
NSString *strippedString = [searchText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
if([strippedString isEqualToString:self.currentFilter]) {
return;
}
self.currentFilter = strippedString;
}
属性 currentFilter 保留当前搜索字符串。
此外,我在 currentFilter-属性 上有一个 RACObserve,以对对此 属性 所做的每个更改做出反应:
[RACObserve(self, currentFilter) subscribeNext:^(NSString* x) {
NSLog(@"Current Filter: %@", x);
// do api calls and everything else
}];
现在我想抑制这个信号。但是当我执行节流调用时,什么也没有发生。永远不会调用 SubscribeNext:
[[RACObserve(self, currentFilter) throttle:500] subscribeNext:^(NSString* x) {
NSLog(@"%@", x); // will never be called
}];
如何实现限制搜索栏中的输入?这里有什么问题?
更新
感谢@malcomhall,我找到了 workaround besides ReactiveCocoa。我将 updateSearchResultsForSearchController-delegate 方法中的代码移动到一个单独的方法中,并使用 performSelector 对其进行调度,并使用 cancelPreviousPerformRequestsWithTarget 取消此调度程序。
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(useTextSearchQuery) object:nil];
[self performSelector:@selector(useTextSearchQuery) withObject:nil afterDelay:1.0];
}
无论如何,我仍然想了解 ReactiveCocoa 的 "throttle" 是如何工作的,为什么不在这种情况下:)
-throttle:
接受 NSTimeInterval
,这是 秒 的浮点规范,而不是毫秒。
鉴于问题中的代码,我希望您会在 500 秒后看到结果。