IOS:主线程后台操作过程中放缓
我使用下面的代码进行什么,我想成为一个后台同步,但主线程放缓甚至即将停止时收到的JSON是大于20或所以记录。这段代码对背景操作有什么问题吗?什么可能会阻止主线程。谢谢你的任何建议。IOS:主线程后台操作过程中放缓
注意下面还有performSelectorOnMainThread一个注释行,其中的应用程序处理的JSON收到,我改变另一个后台线程,但变化似乎并没有帮助。
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) //1
#define kProductsURL [NSURL URLWithString: @"http://~/getproducts.php"]
//in viewDidLoad
if(hasInternet==YES && [loggedIntoServer isEqual:@1]) {
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: kProductsURL];
//previous line grabed data from api.
if (data) {
// [self performSelectorOnMainThread:@selector(fetchData:) withObject:data waitUntilDone:YES];//no longer doing this on main thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self fetchData:data];
});
}
});
;
} //close hasInternet, logged into server.
- (void)fetchData:(NSData *)jsonFeed {
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:jsonFeed
options:kNilOptions
error:&error];
NSMutableArray* latestProducts = [[NSMutableArray alloc] init];
//this is specific to format of JSON
if (![[json objectForKey:@“products"] isKindOfClass:[NSNull class]]) {
latestProducts = [[json objectForKey:@“products"]mutableCopy];
getProducts = latestProducts;
int size = [latestProducts count];
[self.tableView reloadData];
getProducts = [self convertFeedtoObject:latestProducts];
[self importAndSaveProducts:getProducts];//this imports and saves
self.recentlySynced=YES;
}
}
你只是做了一些多余的事情。您在后台线程中调度了数据的提取。但后来你也在后台线程中做了[self.tableView reloadData];
。这就是为什么你的用户界面会受到影响。
试试这个:
if(hasInternet==YES && [loggedIntoServer isEqual:@1])
{
dispatch_async(kBgQueue,^
{
NSData* data = [NSData dataWithContentsOfURL: kProductsURL];
if (data)
{
dispatch_async(dispatch_get_main_queue(),^
{
[self fetchData:data];
});
}
});
}
我所做的是我改变了你的这部分代码:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self fetchData:data];
});
因为你只应做任何修改,以在主线程UI。我的代码的这一部分正在主线程中完成这项工作。
dispatch_async(dispatch_get_main_queue(),^
{
[self fetchData:data];
});
我正在对此进行标记,因为它着重于在后台线程中重新加载数据,这是问题所在。根本没有理由在这里重新加载数据,因为直到所有新数据被下载和解析的最后才会重新加载。我也投了一些其他答案,指出提取数据(解析数据但不会立即影响UI)应该在同一个线程中。 – zztop
您不需要对同一个队列进行嵌套调用。你也应该在主线程上做任何UI工作。欲了解更多信息,看看苹果的Concurrency Programming Guide
在你fetchData方法加载你的表是这样的。
dispatch_async(dispatch_get_main_queue(), {
// Your UI work
[self.tableView reloadData];
})
// Remove second dispatch_async call
//in viewDidLoad
if(hasInternet==YES && [loggedIntoServer isEqual:@1]) {
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: kProductsURL];
//previous line grabed data from api.
if (data) {
[self fetchData:data];
}
});
;
} //close hasInternet, logged into server.
有你的原代码的几个错误,更改为以下:
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0) //CHANGE TO BACKGROUND
#define kProductsURL [NSURL URLWithString: @"http://~/getproducts.php"]
//in viewDidLoad
if(hasInternet==YES && [loggedIntoServer isEqual:@1]) {
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: kProductsURL];
if (data) {
[self fetchData:data];
}
});
} //close hasInternet, logged into server.
更改获取数据到以下几点:
- (void)fetchData:(NSData *)jsonFeed {
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:jsonFeed
options:kNilOptions
error:&error];
NSMutableArray* latestProducts = [[NSMutableArray alloc] init];
//this is specific to format of JSON
if (![[json objectForKey:@"products"] isKindOfClass:[NSNull class]]) {
latestProducts = [[json objectForKey:@"products"]mutableCopy];
getProducts = latestProducts;
int size = [latestProducts count];
//Do this on the main thread:
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
getProducts = [self convertFeedtoObject:latestProducts];
[self importAndSaveProducts:getProducts];//this imports and saves
self.recentlySynced=YES;
}
}
根据如何你的表视图作品以及数据源是什么样子,您可能需要将重载表视图行(使用主队列调度)移至self.recentSynced = YES下。
哪里是主线程? –
dispatch_get_global_queue不是主线程! –
我很喜欢你的'fetchData:'方法。你如何创建'kBgQueue' – marosoaie