heyMax
heyMax

Reputation: 3

Execute a block asynchronously before statement in same method

How to execute a block asynchronously before statement in same method?

The return always execute before block, but if that the commit always equals to No.

I want the block execute before return. How can I do it? I try dispatch_semaphore_t but checkVerifyCode is in main thread. I can't block the main thread.

-(BOOL)checkVerifyCode
{
__block BOOL commit = NO;
    [SMSSDK commitVerificationCode:self.verificationNum.text phoneNumber:self.phoneNumber.text zone:@"86" result:^(NSError *error) {
        if (error) {
            NSString *errInfo = [error.userInfo objectForKey:@"commitVerificationCode"];
            MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
            [hud setMode:MBProgressHUDModeText];
            [hud setLabelText:@"验证码输入错误"];
            [hud setLabelText:errInfo];

            hud.color = [UIColor clearColor];
            hud.labelColor = [UIColor colorWithRed:118/255.f green:214/255.f blue:255/255.f alpha:0.8f];
            hud.detailsLabelColor = [UIColor colorWithRed:118/255.f green:214/255.f blue:255/255.f alpha:0.8f];
            hud.margin = 10.f;
            hud.yOffset = -100.f;
            hud.removeFromSuperViewOnHide = YES;
            [hud hide:YES afterDelay:3];
            NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:commit] forKey:@"bool"];
            [self performSelectorOnMainThread:@selector(setCommit:) withObject:dict waitUntilDone:NO];

        }else
        {
            NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:commit] forKey:@"bool"];
            [self performSelectorOnMainThread:@selector(setCommit:) withObject:dict waitUntilDone:NO];
            commit = YES;
        }
    }];
return commit;

}

Upvotes: 0

Views: 118

Answers (3)

habs93
habs93

Reputation: 105

Rather than return the value 'commit' like you are currently doing, pass into the method a completion block that takes a 'bool' as a parameter. Then the caller would be able to pass code into 'verifyCheckCode' and have it asynchronously executed.

Upvotes: 0

bbum
bbum

Reputation: 162722

You are effectively asking to make an asynchronous method synchronous. And since your call to the checkVerifyCode method is on the main thread, that would require blocking the main thread (which, as noted, is bad idea).

Instead, you should move to having some method somewhere which you can call to update based on the result of the asynchronous method.

I.e.:

  • put up progress indicator and a field that says "Checking your code"
  • modify checkVerifyCode to return void and
  • at the end of the asynchronous call, call some method somewhere:

_

 [self _checkVerifyDone:commit];

And, if you really need it on the main queue:

dispatch_async(dispatch_get_main_queue(), ^{
    [self _checkVerifyDone:commit];
});

Upvotes: 1

Sam
Sam

Reputation: 2579

You can dispatch the entire function to a separate queue, then use dispatch_semaphore to block that queue until the result is returned.

What's your higher level goal here? It seems like a dispatch_notify_group might be what you're looking for, but it's hard to tell from your question. I understand the problem you're trying to solve, but what is the big picture?

Upvotes: 0

Related Questions