我有循环,可以读取多达10万行 当我启动此功能时,它会阻止我的UI直到完成。
for (Item* sp in items){
data = [data stringByAppendingFormat:@"\"%@\",\"%@\","\n", ....];
}
如何将它放在单独的线程中,以便它不会阻止UI?
答案 0 :(得分:2)
我认为你没有提供完整的例子,但简单使用Grand Central Dispatch应该可以解决问题:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (Item* sp in items){
data = [data stringByAppendingFormat:@"\"%@\",\"%@\","\n", ....];
}
// Then if you want to "display" the data (i.e. send it to any UI-element):
dispatch_async(dispatch_get_main_queue(), ^{
self.someControl.data = data;
});
// else simply send the data to a web service:
self.webService.data = data;
[self.webService doYourThing];
});
答案 1 :(得分:0)
这可能适合你
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
for(Item* sp in items)
{
data = [data stringByAppendingFormat:@"\"%@\",\"%@\","\n", ....];
}
dispatch_async(dispatch_get_main_queue(), ^{
//UI updates using item data
});
});
答案 2 :(得分:0)
使用NSInvocationOperation的最佳方式。
NSOperationQueue *OperationQueue=[[NSOperationQueue alloc] init];
NSInvocationOperation *SubOperation=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(LoopOperation) object:nil];
[SubOperation setQueuePriority:NSOperationQueuePriorityVeryHigh]; //You can also set the priority of that thread.
[OperationQueue addOperation:SubOperation];
-(void)LoopOperation
{
for (Item* sp in items)
{
data = [data stringByAppendingFormat:@"\"%@\",\"%@\","\n", ....];
}
dispatch_async(dispatch_get_main_queue(), ^{
//UI updates using item data
});
}
答案 3 :(得分:0)
如果订单在您的循环中无关紧要,我更喜欢在dispatch_apply()
内使用dispatch_async()
。不同之处在于传统的for(...)
循环将所有工作放在一个线程上,而dispatch_apply()
将在多个线程上并行执行单独的迭代,但整体上循环是同步的,其中在所有处理完成之前,循环不会退出。
一个很好的测试,看一下循环中的顺序是否可以向后执行循环并获得相同的结果。