一个接一个地执行任务

Execute task after another

最近我开始为 iOS 开发并遇到了一个问题,这个问题对你来说可能是显而易见的,但我自己无法解决。 我想做的是使用 GCD 提供的多线程一个接一个地执行任务。

这是我获取 JSON 的代码(用单例输入 class) 类别商店

- (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在viewDidAppear中执行。结果通常是之前,之后,然后是JSON。显然我要得到的是之前,json之后

我也尝试用 dispatch_group_notify 来做这个,但没有成功。

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

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

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

我建议在 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];
        }
    }]
}

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

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