我用
https://github.com/ReactiveCocoa/ReactiveCocoa实现了我的第一个代码.
用于登录用户.行[subscriber sendNext:user];被叫两次,但我希望只有一次.并且根本没有调用地图(因此永远不会调用自动登录)
这是我的实施:
-(RACSignal *) login:(NSString *)email pwd:(NSString *)pwd { DDLogInfo(@"Login user %@",email); RACSignal *login = [RACSignal createSignal:^ RACDisposable *(id<RACSubscriber> subscriber) { [PFUser logInWithUsernameInBackground:email password:pwd block:^(PFUser *user,NSError *error) { if (error) { [subscriber sendError:error]; } else { [subscriber sendNext:user]; [subscriber sendCompleted]; } }]; return nil; }]; [login map:^(PFUser *user) { return [self autoLogin:user]; }]; return login; }
这样称呼:
NSString *email = data[@"email"]; NSString *pwd = data[@"pwd"]; [SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeBlack]; RACSignal *login = [[SyncEngine server] login:email pwd:pwd]; [login subscribeCompleted:^ { [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFY_LOGIN_CHANGED object:self]; [SVProgressHUD showSuccessWithStatus:LOC_OK]; [self cancelForm]; }]; [login subscribeError:^(NSError *error) { [SVProgressHUD dismiss]; [AppUrls alertError:LOC_ERROR_LOGING msg:error.userInfo[@"error"]]; }];
解决方法
发生这种情况是因为每当对信号进行订阅时,传递给[RACSignal createSignal:]的块都会执行,并且您的代码会创建两个单独的订阅:
[login subscribeCompleted:^{ ... }]; [login subscribeError:^(NSError *error) { ... }];
如果您只想创建单个订阅,请使用方法 – [RACSignal subscribeError:completed:]:
[login subscribeError:^(NSError *error) { [SVProgressHUD dismiss]; [AppUrls alertError:LOC_ERROR_LOGING msg:error.userInfo[@"error"]]; } completed:^{ [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFY_LOGIN_CHANGED object:self]; [SVProgressHUD showSuccessWithStatus:LOC_OK]; [self cancelForm]; }];