【问题标题】:Execute task after another一个接一个地执行任务
【发布时间】:2015-07-27 19:00:22
【问题描述】:

最近我开始为 iOS 开发并遇到问题,这对您来说可能很明显,但我自己无法解决。 我要做的是使用 GCD 提供的多线程来执行另一个任务。

这是我获取 JSON 的代码(与单例一起放入类中) 分类商店

- (instancetype)initPrivate {
    self = [super init];

    if (self) {
        [self sessionConf];

        NSURLSessionDataTask *getCategories =
        [self.session dataTaskWithURL:categoriesURL
                    completionHandler:^(NSData *data,
                                        NSURLResponse *response,
                                        NSError *error) {
                        if (error) {
                            NSLog(@"error - %@",error.localizedDescription);
                        }

                        NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *) response;

                        if (httpResp.statusCode == 200) {
                            NSError *jsonError;

                            NSArray *json =
                            [NSJSONSerialization JSONObjectWithData:data
                                                            options:NSJSONReadingMutableContainers
                                                              error:&jsonError];
                            if (!jsonError) {
                                _allCategories = json;
                                NSLog(@"allcategories - %@",_allCategories);
                            }
                        }
        }];

        [getCategories resume];
    }

    return self;
}

然后在 ViewController 我执行

- (void)fetchCategories {
    NSLog(@"before");

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
            CategoriesStore *categories = [CategoriesStore sharedStore];
        dispatch_async(dispatch_get_main_queue(), ^(void) {
            _allDirectories = categories.allCategories;
            [self.tableView reloadData];
            NSLog(@"after");
        });
    });
}

-fetchCategories 在 vi​​ewDidAppear 中执行。结果通常是之前,之后,然后是JSON。显然我想要得到的是before, json after

我也尝试使用 dispatch_group_notify 来执行此操作,但没有成功。

我怎样才能让它工作?为什么它不等待第一个任务完成? 谢谢你的帮助! 问候,阿德里安。

【问题讨论】:

    标签: ios objective-c json multithreading grand-central-dispatch


    【解决方案1】:

    我建议在CategoriesStore 中定义一个专用方法,从远程服务器获取数据并将回调作为参数:

    - (void)fetchDataWithCallback:(void(^)(NSArray *allCategories, NSError* error))callback
    {
    
        NSURLSessionDataTask *getCategories =
            [self.session dataTaskWithURL:categoriesURL
                        completionHandler:^(NSData *data,
                                            NSURLResponse *response,
                                            NSError *error) {
                            if (error) {
                                NSLog(@"error - %@",error.localizedDescription);
                                callback(nil, error);
                                return;
                            }
    
                            NSError *jsonError = nil;
    
                            NSArray *json =
                            [NSJSONSerialization JSONObjectWithData:data
                                                            options:NSJSONReadingMutableContainers
                                                              error:&jsonError];
                            if (!jsonError) {
                                _allCategories = json;
                                NSLog(@"allcategories - %@",_allCategories);
                                callback(_allCategories, nil);
                            } else {
                                callback(nil, jsonError);
                            }
            }];
    
            [getCategories resume];
    }
    

    你可以在你的ViewController中使用它:

    - (void)fetchCategories {
        [[CategoriesStore sharedStore] fetchDataWithCallback:^(NSArray *allCategories, NSError* error) {
            if (error) {
                // handle error here
            } else {
                _allDirectories = allCategories;
                [self.tableView reloadData];
            }
        }]
    }
    

    通过这种方式,您将在数据加载和解析后重新加载表格视图。

    【讨论】:

      【解决方案2】:

      你必须等待重新加载数据,所以你可以做这样的事情,如果你不想等待整个块并且只是为了获取,另一个选择是使用自定义NSLock

      dispatch_sync(dispatch_get_main_queue(), {
          _allDirectories = categories.allCategories;
          [self.tableView reloadData];
      }
      NSLog(@"after");
      

      【讨论】:

        【解决方案3】:

        我使用了@sgl0v 建议的方法,虽然这不是我期望的解决方案。 另一种方法是使用通知中心并监听事件的发生。

        【讨论】:

          猜你喜欢
          • 2018-03-30
          • 2014-07-15
          • 2021-08-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-10-02
          • 1970-01-01
          相关资源
          最近更新 更多