【问题标题】:What is the proper way of designing this viewModel with blocks in MVVM design?在 MVVM 设计中使用块设计此视图模型的正确方法是什么?
【发布时间】:2015-07-29 13:57:36
【问题描述】:

我正在使用 MVVM 设计为我的应用程序开发注册功能。

我创建了一个 sharedInstance 类并使用如下块实现了 register 方法:

- (void)registerUserWithName:(NSString *)name
                   phone:(NSString *)phone
                password:(NSString *)password
              completion:(CompletionBlock)aCallback
{
    UserModel *user = [[UserModel alloc] init];
      user.name = name;
      user.phone = phone;
      user.password = password;

[[self.client registerUser:user].task continueWithBlock:^id(BFTask *task) {
    if (task.error) {
        aCallback(NO, task.error);
        return nil;
    }
    aCallback(YES, nil);
    return nil;
}];
}

在 MVC 设计中,我会这样做来调用这个方法:

 GlobalFunctions *function = [GlobalFunctions sharedInstance];
[function registerUserWithName:name phone:number password:password completion:^(BOOL isSuccess, NSError *error) {
    if(isSuccess){
        ViewController *vc = [[ViewController alloc]init];
    [self.navigationController pushViewController:vc animated:YES];
    }
}];

我尝试将此代码应用于 MVVM 设计。在我的 viewModel 中,我有:

-(BOOL)registerUserWithUser:(NSString*)name withPhone: (NSString*)number withPassword: (NSString*)password{
RBCFunctions *function = [RBCFunctions sharedInstance];
[function registerUserWithName:name phone:number password:password completion:^(BOOL isSuccess, NSError *error) {
    return isSuccess;
}];
}

但是,这不起作用,因为我收到编译器错误:

Incompatible block pointer types sending BOOL

我怎样才能正确地实现它?

【问题讨论】:

    标签: ios objective-c mvvm viewmodel objective-c-blocks


    【解决方案1】:

    您遇到的错误是因为您试图从返回类型为void 的块中返回一个布尔值。看看我这段代码中的cmets,

    -(BOOL)registerUserWithUser:(NSString*)name withPhone: (NSString*)number withPassword: (NSString*)password{ 
    // Begin method that returns BOOL
        RBCFunctions *function = [RBCFunctions sharedInstance];
    // Call function that takes a completion handler that returns VOID!
        [function registerUserWithName:name phone:number password:password completion:^(BOOL isSuccess, NSError *error) {
            // Returning BOOL in block that should return VOID!
            return isSuccess;
        }];
        // NO RETURN VALUE!
    }
    

    如果您正在处理块(AKA 异步编程)并且想要传递值,则需要创建更多块,以便您的代码如下所示:

    -(void)registerUserWithUser:(NSString*)name withPhone: (NSString*)number withPassword: (NSString*)password handler:(void(^)(BOOL success))handler{
    RBCFunctions *function = [RBCFunctions sharedInstance];
    [function registerUserWithName:name phone:number password:password completion:^(BOOL isSuccess, NSError *error) {
        !handler ?: handler(isSuccess);
        // The above line is equivalent to:
        /*
        if (handler) {
            handler(isSuccess);
        }
        */
    }];
    }
    

    这样你就可以这样称呼它:

    [self registerUserWithUser:@"Badass" withPhone:@"01234567891" withPassword:@"password" handler:^(BOOL OK) {
        if (OK) {
            // Boss!
        } else {
            // Ahh NO!
        }
    }];
    

    需要注意的几点:

    • 1) 如果你的块变量是 nil 并且你调用它(即myBlock(args)),那么你的应用程序将会崩溃。您需要在调用块之前测试是否存在;最简单的方法是使用三元运算符:!myBlock ?: myBlock(args);

    • 2) 你确定你的RCBFunctions 类需要是单例吗?一旦你了解了单例,就很容易在不需要它们时到处使用它们(我以前自己做过)。将注册码添加到UserModel 类中会不会更容易? IE。 :

      [myUser registerWithCallback:^(BOOL success) { // Blah blah }];

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-24
      • 1970-01-01
      相关资源
      最近更新 更多