Why the signal is called twice in ReactiveCocoa?

你说的曾经没有我的故事 提交于 2019-12-03 07:44:38

This happens because the block passed to +[RACSignal createSignal:] executes whenever a subscription to the signal is made, and your code creates two separate subscriptions:

[login subscribeCompleted:^{ ... }];

[login subscribeError:^(NSError *error) { ... }];

If you only want to create a single subscription, use the method -[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];
    }];
NachoSoto

While sometimes this solution might be all you need, sometimes you do want to make sure the subscription block is only called once, maybe because it produces side effects. In this case, you can return the signal calling -replay:

return [[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;
}] map:^(PFUser *user) {
    return [self autoLogin:user];
}] replay];

This new, derived signal will send the the same messages or error to all subscribers. If the signal completes, and there is a new subscriber, this will immediately receive all messages as well.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!