首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GCD等待NSURLSessionDataTask完成

GCD等待NSURLSessionDataTask完成
EN

Stack Overflow用户
提问于 2014-10-18 12:23:04
回答 1查看 1.3K关注 0票数 1

我有一个UITableViewController,称为TableViewControllerA,它是另一个对象APICallerB的委托,它是我为与API通信而创建的。通过一个NSURLSessionDataTask,APICallerB设置它的一个属性,然后将其设置为TableViewControllerA的属性之一。

下面是tableViewControllerA的viewDidLoad方法:

代码语言:javascript
复制
- (void)viewDidLoad {

    [super viewDidLoad];

    // init instance of APICallerB
    APICallerB *acb = [[APICallerB alloc] init];

    // Set TableViewControllerA as delegate
    tvcA.delegate = self;


    [acb makeAPICallWithArgument:self.argument];


    self.property1 = acb.property2;
}

我的问题是:等待[acb makeAPICallWithARgument:self.argument]完成的最佳方法是什么,这样self.property1 = acb.property2才能工作?我假设可以使用GCD (‘调度_同步’?)但是,作为iOS/Objective的新手,我不知道该在哪里使用它。还是将其中一个或两个项目移到别处比较好?

下面是来自APICallerB的方法:

代码语言:javascript
复制
- (void)makeAPICallWithArgument:(NSString *)arg
{


    NSString *requestString = [NSString stringWithFormat:@"http://%@:%@@apiurl.com/json/Request?arg=%@", API_USERNAME, API_KEY, arg];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    config.HTTPAdditionalHeaders = @{@"Accept" : @"application/json"};
    NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];

    NSURL *url = [NSURL URLWithString:requestString];
    NSURLRequest *req = [NSURLRequest requestWithURL:url];

    NSURLSessionDataTask *dataTask = [urlSession dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        NSArray *ar = [jsonObject[@"Result"] objectForKey:@"results"];
        self.property2 = ar;
        }];

  [dataTask resume];
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-18 13:44:13

您正在调用异步方法,因此应该使用异步模式。例如,完成块实现可能如下所示:

代码语言:javascript
复制
- (void)makeAPICallWithArgument:(NSString *)arg completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler
{
    NSString *requestString = [NSString stringWithFormat:@"http://%@:%@@apiurl.com/json/Request?arg=%@", API_USERNAME, API_KEY, arg];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    config.HTTPAdditionalHeaders = @{@"Accept" : @"application/json"};
    NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];

    NSURL *url = [NSURL URLWithString:requestString];
    NSURLRequest *req = [NSURLRequest requestWithURL:url];

    NSURLSessionDataTask *dataTask = [urlSession dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (completionHandler) {
            if (error) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    completionHandler(nil, error);
                });
            } else {
                NSError *parseError;
                NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
                dispatch_async(dispatch_get_main_queue(), ^{
                    completionHandler(jsonObject[@"Result"][@"results"], parseError);
                });
            }
        }
    }];

    [dataTask resume];
}

你会把它叫做:

代码语言:javascript
复制
[acb makeAPICallWithArgument:self.argument completionHandler:^(NSArray *results, NSError *error){
    // you'd probably first check to make sure you didn't have an error

    self.property1 = results;
}];

以下是几点小小的意见:

  1. 我可能不会每次都创建一个新的会话。如果您希望执行一个以上的调用,请将此会话保存为以后的请求。

  1. 您的makeAPICallWithArgument正在更新一个属性,您稍后将尝试检索该属性。我将退出该属性,并将值作为参数传递回完成块。

  1. 我在这里添加了一个小错误处理。

  1. 你的[jsonObject[@"Result"] objectForKey:@"results"]看起来不太可能是对的。您真的有JSON返回一个关键字为“结果”的字典,而在另一个字典中返回的是“结果”键。如果是的话,很好,但看起来很可疑。即使这是您的JSON格式,我也会将其简化为jsonObject[@"Result"][@"results"]

  1. 在其他地方,有人建议你可以考虑信号量。这几乎总是个坏主意。用于使异步方法同步运行。但你永远不想阻止主队列。 使用完成块模式消除了对信号量的需求。Apple提供异步API是有原因的,所以我们在使用它时应该采用异步模式。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26439677

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档