我正在尝试重构一些NSJSONSerialization
代码,以便它不在主线程上。目前该应用程序有点迟缓。
我想将此代码重构为以下内容,并且语法问题尤其是错误处理问题。例如,如果我使用现有代码(requestData:方法)并将其放在
中 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
});
该表不再加载任何数据。
感谢您的帮助。
-(void)requestData {
[HUD showUIBlockingIndicatorWithText:@"Fetching JSON"];
NSError *requestError = nil;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL
URLWithString:kURL]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&requestError];
NSError *jsonParsingError = nil;
if (requestError)
{
NSLog(@"sync. request failed with error: %@", requestError);
}
else
{
// handle data
publicData = [NSJSONSerialization JSONObjectWithData:response
options:0
error:&jsonParsingError];
publicDataArray = [publicData objectForKey:@"data"];
}
/*
for(publicDataDict in publicDataArray) {
NSLog(@"data output is %@",[publicDataDict objectForKey:@"title"]);
}
*/
[self.mainTableView reloadData];
[HUD hideUIBlockingIndicator];
}
这是我想要使用的代码。
-(void)viewDidAppear:(BOOL)animated
{
[HUD showUIBlockingIndicatorWithText:@"Fetching Data"];
//1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//code executed in the background
//2
NSData* ghData = [NSData dataWithContentsOfURL:
[NSURL URLWithString:kURL]
];
//3
NSDictionary* json = nil;
if (ghData) {
json = [NSJSONSerialization
JSONObjectWithData:ghData
options:kNilOptions
error:nil];
}
//4
dispatch_async(dispatch_get_main_queue(), ^{
//code executed on the main queue
//5
[self.tableView reloadData];
[HUD hideUIBlockingIndicator];
});
});
}
答案 0 :(得分:2)
很多人都认为向后台发送进程会自动消除他们应用程序的任何迟缓,这是一个错误的假设。如果将CPU密集型任务发送到后台,它也会阻止CPU。要使多线程对你有利,你必须对它有条不紊。
现在解决你的问题,最简单的解决方案就是让你使用Apple提供的东西,NSURLConnection是你最好的选择,永远不要使用[NSData dataWithContentsOfURL:]这是一个明确的不。 问题不在于NSJSONSerialization,而是网络请求。
你真的有两种选择。
1)使用NSRULConnection委托方法并将您的JSON序列化方法放在 - connectionDidFinishLoading:delegate方法
2)使用NSURLConnection的块方法[NSURLConnection sendAsynchronousRequest:queue:completionHandler:](我的首选)
-(void)viewDidAppear:(BOOL)animated
{
[HUD showUIBlockingIndicatorWithText:@"Fetching Data"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
NSError *jsonError = nil;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
if (jsonError) {
NSLog(@"Error parsing JSON");
//Optionally display error message here
}else{
self.globalDictionary = jsonDict;
[self.tableView reloadData];
[HUD hideUIBlockingIndicator];
}
}else
{
NSLog(@"Error with request");
[HUD hideUIBlockingIndicator];
//Optionally display error message here
}
}];
}
注意: globalDictionary是一个填充表格的NSDictionary实例。
答案 1 :(得分:1)
因此,可能的猜测是这可能是表重载方法将在之前调用。所以在最后你可以重新加载表格,如下所示。
-(void)viewDidAppear:(BOOL)animated
{
[HUD showUIBlockingIndicatorWithText:@"Fetching Data"];
//1
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//code executed in the background
//2
NSData* ghData = [NSData dataWithContentsOfURL:
[NSURL URLWithString:kURL]
];
//3
NSDictionary* json = nil;
if (ghData) {
json = [NSJSONSerialization
JSONObjectWithData:ghData
options:kNilOptions
error:nil];
}
//4
[self performSelectorOnMainThread:@selector(reloadTable) withObject:nil waitUntilDone:NO];
});
}
之后就这样了。
-(void)reloadTable {
[self.tableView reloadData];
[HUD hideUIBlockingIndicator];
}
如果未调用tableview数据源委托方法,则检查它是否被调用,然后设置UITableView委托。
答案 2 :(得分:0)
如果要重构代码,请使用函数。您应该编写一个逻辑/代码,旨在在单独的函数中执行某项任务,并且在正常情况下,任何函数中的LOC也不应超过20。
谈到你的问题,它看起来你说得对,但我没有看到你定义tableView的来源,请检查你是否已将JSON转换为任何容器对象viz字典或数组。
-(void)viewDidAppear:(BOOL)animated
{
[HUD showUIBlockingIndicatorWithText:@"Fetching Data"];
[self fetchData];
}
-(void)fetchData
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// switch to a background thread and perform your expensive operation
NSData* ghData = [NSData dataWithContentsOfURL:
[NSURL URLWithString:kURL]
];
NSDictionary* json = nil;
if (ghData)
{
json = [NSJSONSerialization
JSONObjectWithData:ghData
options:kNilOptions
error:nil];
}
dispatch_async(dispatch_get_main_queue(), ^{
// switch back to the main thread to update your UI
[self.tableView reloadData];
[HUD hideUIBlockingIndicator];
});
});
}
答案 3 :(得分:-3)