0

短版:是否可以像使用 NSNotificationCenter 一样使用 RACMulticastConnection?我的意思是即使对另一个呼叫 [connection connect] 也保持订阅的块有效?

长版:在不同的订阅者中,我共享一个对 RACMulticastConnection 的引用。那些发起请求的人通过 loginRequest!=nil 而那些只想听的订阅者使用 loginRequest==nil:

RACMulticastConnection *connection = [self.appModel loginRequest:loginRequest];
[connection connect]; //I initiate the request


[connection.signal subscribeNext:^(RACTuple* responseTuple) {

} error:^(NSError *error) {

} completed:^{

}];

在其他模块中,我只是订阅和收听:

RACMulticastConnection *connection = [self.appModel loginRequest:nil];
[connection.signal subscribeNext:^(RACTuple* responseTuple) {

} error:^(NSError *error) {

} completed:^{

}];

当我调用 [connection connect] 时;一切正常。通知订阅者。但是如果我想用 [connection connect] 再次向服务器重复请求;我刚刚收到旧响应的成功信号。

基本想法是我想创建一次 RACMulticastConnection 并将其分享给潜在的订阅者。监听者传递 nil 参数,发起请求者传递非 nil 参数并调用 [connection connect];但它不会触发RACSignal createSignal:中定义的块。

当 RACMulticastConnection 不存在时,只创建一次 RACSignal。self.loginRequestConnection是模型的属性。该属性在应用程序中共享给订阅者:

- (RACMulticastConnection*) loginRequest:(LoginRequest*)request {

    self.loginRequest = request;

    if(! self.loginRequestConnection) { // the instance of RACMulticastConnection shared among the subscribers

        @weakify(self);
        RACSignal* networkRequest = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

            __block Response* blockResponse = nil;

            @strongify(self);

            [_serviceClient login:self.loginRequest success:^(TSNApiResponse *response, TSNError *error) {

                blockResponse = response;
                [subscriber sendNext:RACTuplePack(response, error)];
                [subscriber sendCompleted];

            } failure:^(TSNError *error) {

                [self cleanUpRequestOnError:error subscriber:subscriber blockResponse:blockResponse blockRequest:self.loginRequest];

                [subscriber sendError:error];
            }];

            return [RACDisposable disposableWithBlock:^{

                [_serviceClient cancelRequest:self.loginRequest];
            }];

        }];

        self.loginRequestConnection = [networkRequest multicast:[RACReplaySubject subject]];
    }

    return self.loginRequestConnection;
}

有什么正确的方法可以使连接再次触发 RACSignal 中的块?谢谢你。

4

1 回答 1

1

我用过 FBKVOController。使用 FBKVOController 完成的代码是使用 ReactiveCocoa 完成的代码的一小部分:

- (void) loginRequest:(TSNLoginRequest*)request {

    [_serviceClient login:request success:^(TSNApiResponse *response, TSNError *error) {

        self.loginResponseTuple = [TSNResponseTuple responseTuple:response error:error];

    } failure:^(TSNError *error) {

        self.loginResponseTuple = [TSNResponseTuple responseTuple:nil error:error];

   }];
}

发出请求:

[self.appModel loginRequest:loginRequest];

观察反应:

[_KVOController observe:self.appModel keyPath:@"loginResponseTuple" options:NSKeyValueObservingOptionNew block:^(TSNStartupScreenViewModel* observer, TSNAppModel* observed, NSDictionary *change) {

    TSNResponseTuple* responseTuple = change[NSKeyValueChangeNewKey];

    @strongify(self);
    if([responseTuple.error isError]) {

        [TSNAppUtilities showError:(TSNError *)(responseTuple.error) completion:^(OHAlertView *alert, NSInteger buttonIndex) {

            if(buttonIndex == alert.firstOtherButtonIndex) {

                // ... process selection
            }
        }];
    } 
}];
于 2014-05-20T19:25:47.803 回答