2015-07-21 140 views
0

概述:我正在使用Amazon DynamoDB作为我的登录服务。我的登录方法在UserAccount.m中看起来像这样。我在LoginViewController.m上调用这个类的方法登录按钮tap:目标c-如何在执行任何其他代码之前确保块执行得更进一步?

+ (BOOL)loginWithUsername:(NSString *)username password:(NSString *)password{ 

AWSDynamoDBObjectMapper *dynamoDBObjectMapper = [AWSDynamoDBObjectMapper defaultDynamoDBObjectMapper]; 
BOOL __block isLoginSuccessful = NO; 

[[dynamoDBObjectMapper load:[User class] hashKey:username rangeKey:@"key"] 
continueWithBlock:^id(AWSTask *task) { 
    if (task.error) { 
     NSLog(@"The request failed. Error: [%@]", task.error); 
    } 
    if (task.exception) { 
     NSLog(@"The request failed. Exception: [%@]", task.exception); 
    } 
    if (task.result) { 
     //Do something with the result.    
     User *user = task.result; // User is a model I'm using 
     NSLog(@"pass: %@", user.password); 

     // Check returned password from DynamoDB with user-supplied password. 
     if ([user.password isEqualToString:password]) { 
      isLoginSuccessful = YES; 
     } 
    } 
    return nil; 
}]; 

return isLoginSuccessful; // <-- Issue: function returns before block executes and isLoginSuccessful value is changed. 
} 

问题是函数返回之前执行块。我的尝试:

我)我读了有关使用dispatch groups on this SO question

II)尝试在这样的主线程中执行的方法- (AWSTask *)load:(Class)resultClass hashKey:(id)hashKey rangeKey:(id)rangeKey但仍函数返回前块执行完毕:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [[dynamoDBObjectMapper load:[User class] 
         hashKey:username 
         rangeKey:@"key"] continueWithExecutor:[AWSExecutor mainThreadExecutor] withBlock:^id(AWSTask *task) { 
     if (!task.error) { 
      User *user = task.result; 
      NSLog(@"pass: %@", user.password); 
      //Do something with the result. 
      if ([user.password isEqualToString:password]) { 
       isLoginSuccessful = YES; 
      } 
     } else { 
      NSLog(@"Error: [%@]", task.error); 


     } 
     return nil; 
    }]; 
}); 

上午我错过了某些东西/在我的方法中做错了什么?任何对正确方向的建议都会很有帮助。谢谢!

编辑1:包含从那里loginWithUsername类的方法被调用函数:

@IBAction func login(sender: AnyObject) { 

    if(UserAccount.loginWithUsername(txtEmail.text, password: txtPassword.text)){ 
     println("SUCCESS") 
     lblIncorrect.hidden = true 
    } 
    else{ 
     println("Incorrect username/password") 
     lblIncorrect.hidden = false 
    } 


} 
+0

尝试使用完毕块 – Rajal

回答

1

它是块被执行的“在后台” GCD的基本思想,因此,控制流程可以在任务完成之前返回消息的发送者。这是因为任务是一个潜在的长跑者,并且你不想阻止发送控制流,尤其是,如果它是主线程。

如果您想在完成操作后执行代码,只需将其添加到块。这是login()中的代码:将if添加到块并删除块变量和返回值。制定方法void

有一个大致的模式:

-(IBAction)doSomething:(id)sender 
{ 
    [self executeOperation]; // Method becomes void 
    // Remove code processing on result 
} 

-(void)executeOperation // Method becomes void 
{ 
    [receiver longRunnerWithBlock:^(id result) 
    { 
    … 
    // Add code processing on result 
    } 
} 

请小心,该块可能在不同的线程比主线程中运行,所以你必须派遣它在主线程上,如果是UI相关。

0

或者你可以只取谷歌iOS的框架代码的网页,并做了简单的方法是这样的:

- (void)runSigninThenInvokeSelector:(SEL)signInDoneSel { 


    if (signInDoneSel) { 
     [self performSelector:signInDoneSel]; 
    } 

} 
相关问题