How to ensure completion of a async operation before continuing with execution

青春壹個敷衍的年華 提交于 2019-12-10 11:57:36

问题


I am building an iOS app and some part of its code relies on the success/failure value returned from a particular task.This tasks involves callbacks from a library. I want the return value from this task to be returned only after the callback has returned either success/failure. But since I wrote a sequential code the return value is returned even before the callback returns a success/failure.

I looked into using modal view controllers and from what I understand I can make the task execute from this view controller and then return the code back.

But this also doesn't suit my requirements as when the code which initiates the callback sequence is executed I don't want a new view controller to be displayed. Although there is a certain callback which requires me to prompt the user for information. I do this in a popover and I considered making the view controller within the popover modal. But then the callbacks will still be part of the main thread and I won't receive them when my popover is presented modally(?).

With my current understanding of these concepts I don't know how to proceed. Is there some way to do this in iOS?

EDIT: The code does something like this

//In CustomTableViewController

-(void) someFunc
{
   ENUM_NAME code = [TaskController startTheTask:args];
   if(code == SUCCEEDED)
   {
      //Do Something
   }
   if(code == FAILED)
   {
      //Do Something Else
   }
}

//In TaskController

-(ENUM_NAME) startTheTask:args
{
   startWorkflow(args); //This function registers callback function with the library. 
   return finalCode; //This is returned even before it is set to SUCCEEDED/FAILED
}

-(void) onCallback:params
{
    MSG_TYPE msg = [params getMsg];

    if(msg == TASK_FAILED)
       finalCode = FAILED;
    if(msg == TASK_SUCCEEDED)
       finalCode = SUCCEEDED;
    if(msg == TASK_SHOW_PROMPT)
    {  
       [PopOverController showPopOver];
    }
}

-(void) onUserInfoAdded
{
    //This is called when Confirm is clicked in the popover
    continueWorkflow(params); //asks for the next callback to happen
}

-(void) onCancleClicked
{
    //This is called when Popover is dismissed without entering Info
    cancleWorkflow(params); //asks for result of the workflow through callback
}

回答1:


You can use GCD. For example:

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();

    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{           
         //put one process here
         dispatch_group_leave(group);  //when done
    });

    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{           
         //put another process here
         dispatch_group_leave(group); //when done
    });

    // All updates finished
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
         // add last steps here after all processess are finished
    });

    dispatch_release(group);



回答2:


You can use a semaphore to delay the execution until a block returns:

__block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
__block NSData *dataFromTheBlock = nil;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // block implementation
    // dataFromTheBlock = some data;
    dispatch_semaphore_signal(semaphore);
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);


来源:https://stackoverflow.com/questions/23125912/how-to-ensure-completion-of-a-async-operation-before-continuing-with-execution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!