最近我开始为iOS开发并面临一些问题,这对你来说可能是显而易见的,但我自己无法解决这个问题。 我尝试做的是使用GCD提供的多线程执行另一个任务。
这是我获取JSON的代码(用singleton放在类中) CategoriesStore
- (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来做这件事,但没有工作。
我怎样才能让它发挥作用?为什么它不等待第一个任务完成? 感谢您的帮助! 此致,阿德里安。
答案 0 :(得分:0)
您必须等待重新加载数据,以便您可以执行此类操作,如果您不想等待整个块,则另一个选项是仅使用自定义NSLock
dispatch_sync(dispatch_get_main_queue(), {
_allDirectories = categories.allCategories;
[self.tableView reloadData];
}
NSLog(@"after");
答案 1 :(得分:0)
我建议在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 :(得分:0)
我使用@ sgl0v建议的方法,虽然它不是我预期的解决方案。 另一种方法是使用通知中心并监听事件发生。