首页 > 解决方案 > NSURLSession 同步调用

问题描述

我不确定是否有明确的答案。我知道如何使用块和完成处理程序,但是为此我不能使用它们并且需要同步调用该方法:

- (void)codePathWithURL:(NSURLRequest *)request {
    // Create session
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    config.URLCache = nil;
    config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
    
    NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:nil];


    // Using semaphores
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    NSURLSessionDataTask *sessionTask = [urlSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        responseData = data;
        httpResponse = (NSHTTPURLResponse *)response;
        outError = error;
        
        dispatch_semaphore_signal(semaphore);
    }];
    [sessionTask resume];
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    // do something with data 
}

我在这里看到的问题是锁定了主线程。我该如何做才能使主线程不被阻塞?

标签: objective-cnsurlsession

解决方案


只是一个快速而肮脏的尝试来帮助你开始......也许使用条件?

// Call this on the background NOT on the main thread
- ( ... ) some message
{
    // Added stuff
    __block BOOL done = NO;      // ... use now to set data as well
    __block NSString * data;     // ... or whatever is needed
    NSCondition * condition = NSCondition.new;

    // Your original stuff
    // Create session
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    config.URLCache = nil;
    config.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
    
    NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:nil];
 NSURLSessionDataTask *sessionTask = [urlSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        responseData = data;
        httpResponse = (NSHTTPURLResponse *)response;
        outError = error;

        // Added stuff
        condition.lock;
        done = YES;

        // Set data
        data = ... something ...        

        condition.broadcast;
        condition.unlock;
    }];

    [sessionTask resume];

    // New stuff
    condition.lock;
    while ( ! done )
    {
      condition.wait;
    }
    condition.unlock;

    // something like ...
    return data;
...

推荐阅读