How to wrap an asynchronous method that takes a block and turn it synchronous in Objective-C

后端 未结 4 939
感情败类
感情败类 2021-02-02 18:03

I want to wrap an async API that look like this:

[someObject completeTaskWithCompletionHandler:^(NSString *result) {

}];

into a synchronous m

相关标签:
4条回答
  • 2021-02-02 18:16

    dispatch_semaphore_wait blocks the main queue in your example. You can dispatch the async task to a different queue:

    __block NSString *returnResult;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0UL);
    dispatch_async(queue,^{
         result = [someObject completeTaskSynchronously];
    });
    

    Or use some other system, like NSRunLoop:

       __block finished = NO;
       [self completeTaskWithCompletionHandler:^(NSString *result) {
           resultResult = result;
           finished = YES;
       }];
        while (!finished) {
            // wait 1 second for the task to finish (you are wasting time waiting here)
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1]];
        }
    
    0 讨论(0)
  • 2021-02-02 18:16

    I think the better solution will be NSRunLoop as given below. It's simple and working fine.

    - (NSString *)getValue {
    
        __block BOOL _completed = NO;
        __block NSString *mValue = nil;
    
        [self doSomethingWithCompletionHandler:^(id __nullable value, NSError * __nullable error) {
            mValue = value;
            _completed = YES;
        }];
    
        while (!_completed) {
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        }
    
        return mValue;
    }
    
    0 讨论(0)
  • 2021-02-02 18:17

    You can try to use NSOperations for this doing your things asynchronously.

    0 讨论(0)
  • 2021-02-02 18:18

    Using an NSRunLoop is the easiest to do here.

    __block NSString* result = nil;
    [self completeTaskWithCompletionHandler:^(NSString *resultstring) {
        result = resultstring;
    }];
    while (!result) {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }
    
    0 讨论(0)
提交回复
热议问题