ios - Objective c- How to make sure block executes before executing any other code further? -


overview : using amazon dynamodb login service. , login method looks in useraccount.m. , calling class method in loginviewcontroller.m on login button tap:

+ (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 result.                       user *user = task.result;   // user model i'm using           nslog(@"pass: %@", user.password);           // check returned password dynamodb user-supplied password.          if ([user.password isequaltostring:password]) {              isloginsuccessful = yes;          }      }      return nil;  }];   return isloginsuccessful;  // <-- issue: function returns before block executes , isloginsuccessful value changed. } 

the issue function returns before block executes. tried:

i) read using dispatch groups on question

ii) tried execute method - (awstask *)load:(class)resultclass hashkey:(id)hashkey rangekey:(id)rangekey on main thread still function returns before block execution finishes.:

   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 result.             if ([user.password isequaltostring:password]) {                 isloginsuccessful = yes;             }         } else {             nslog(@"error: [%@]", task.error);           }         return nil;     }]; }); 

am missing out here/ doing wrong in approach? suggestion towards right direction helpful. thank you!

edit 1: including function loginwithusername class method being called:

@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     }   } 

it basic idea of gcd blocks executed "in background", control flow can return sender of message before task finished. is, because task potential long runner , not want block sending control flow, esp. if main thread.

if want execute code after finishing operation, add block. code inside login(): add if block , remove block variable , return value. make method void.

to have general pattern:

-(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   } } 

please take care, block potentially run on different thread main thread, have dispatch on main thread, if ui related.


Comments