ios – 为什么在ReactiveCocoa中调用信号两次?

我用 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];
    }];

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...