我正在努力通过AFNetworking和Reactive Cocoa处理对Web服务的多个请求的方式。在这种情况下,用户要求API为字符/整数搜索输入提供一堆建议,以从列表中选择城市。
这是我的代码:
首先,用户键入超过3个字符/整数时将立即执行的方法
- (void)fetchData:(NSString *)searchText
{
NSLog(@"%@", searchText);
if ([searchText validateStringwithPattern:BKPostcodeRegEx]) {
self.searchURL = [NSString stringWithFormat:@"%@location/postalCode/%@/%@", BKBaseURL, self.countryCode, searchText];
} else if ([searchText validateStringwithPattern:BKCityRegEx]) {
self.searchURL = [NSString stringWithFormat:@"%@location/city/%@/%@", BKBaseURL, self.countryCode, searchText];
} else {
NSLog(@"Error Alert - No Valid Input");
return;
}
RAC(self, searchResults) = [[[self postRequest] map:^(NSDictionary *json) {
NSArray *results = json[@"data"][@"locations"];
return results;
}] catch:^(NSError *error) {
return [RACSignal return:@[]];
}];
}
现在这是我实际创建信号并将其传递回
self.searchResults
的地方:- (RACSignal *)postRequest
{
return [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[self.requestOperationManager GET:self.searchURL parameters:self.params success:^(AFHTTPRequestOperation *operation, id responseObject) {
[subscriber sendNext:responseObject];
[subscriber sendCompleted];
}failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[subscriber sendError:error];
}];
return [RACDisposable disposableWithBlock:^{
[self.requestOperationManager.operationQueue cancelAllOperations];
}];
}] doError:^(NSError *error) {
NSLog(@"error: %@", [error description]);
}] throttle:0.5];
}
我认为问题在于,我在当前信号之前的信号完成之前就开始订阅该信号,因此在我尝试再次订阅时引起异常。
*由于未捕获的异常“ NSInternalInconsistencyException”而终止应用程序,原因:“信号名:[[[[+ createSignal:] -doError:] -throttle:0.500000]
-map:] -catch:已绑定到对象的关键路径“ searchResults”,并添加了信号
名称:[[[[+ createSignal:] -doError:]
-throttle:0.500000] -map:] -catch:是未定义的行为'
我的猜测是,我必须在postRequest方法中尝试类似的方法,但这似乎开箱即用:
if (self.requestOperationManager.operationQueue.operationCount == 1) {
NSLog(@"cancel all operations");
[self.requestOperationManager.operationQueue cancelAllOperations];
[subscriber sendCompleted];
}
最佳答案
您只能在任何给定对象的键路径上调用RAC()
。看来-fetchData:
可以被多次调用,这将导致在同一对象和键路径上多次调用RAC()
。
通常,您以某种设置方法(例如初始化程序或RAC()
)调用-[UIViewController loadView]
,以便仅被调用一次。与其等到用户键入超过3个字符然后调用-fetchData:
,不如考虑如何创建一个在用户键入超过3个字符时发送值的信号,并将该信号分配给RAC()
属性。例如(完全未经测试):
- (void)someInitializationMethod
{
RACSignal *moreThan3 = [[myTextField rac_textSignal] filter:^(NSString *text) {
return [text length] > 2;
}];
RAC(self, searchResults) = [self rac_liftSelector:@selector(fetchData:) withSignals:moreThan3];
}
- (void)fetchData:(NSString *)searchText
{
if ([searchText validateStringwithPattern:BKPostcodeRegEx]) {
// ... etc ...
}
return [[[self postRequest] map:^(NSDictionary *json) {
NSArray *results = json[@"data"][@"locations"];
return results;
}] catch:^(NSError *error) {
return [RACSignal return:@[]];
}];
}
- (RACSignal *)postRequest
{
// ... etc ...
关于ios - 短时间内 react 性 cocoa 和多个AFNetworking请求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23059512/