一个接一个地执行任务
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 建议的方法,尽管这不是我预期的解决方案。
另一种方法是使用通知中心并监听事件的发生。
最近我开始为 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 建议的方法,尽管这不是我预期的解决方案。 另一种方法是使用通知中心并监听事件的发生。