我正在努力通过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/

10-10 19:43