2015-07-21 139 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]; 
    } 

} 
相關問題