非常通用的问题,有没有办法在不阻止UI加载的情况下调用我经常使用的方法?
答案 0 :(得分:7)
您可以使用Grand Central Dispatch:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, kNilOptions), ^{
// Call your method.
});
答案 1 :(得分:5)
你肯定想用Grand Central Dispatch来做这件事,但我只是想指出GCD有一个方法构建只是为了这种事情。 dispatch_apply()
在您选择的队列上执行其块的指定次数,当然,跟踪您正在进行的迭代。这是一个例子:
size_t iterations = 10;
dispatch_queue_t queue = dispatch_queue_create("com.my.queue", DISPATCH_QUEUE_SERIAL);
dispatch_apply(iterations, queue, ^(size_t i) {
NSLog(@"%zu",i);// Off the main thread.
dispatch_async(dispatch_get_main_queue(), ^{
// Go back to main queue for UI updates and such
});
});
答案 2 :(得分:2)
您可以使用:
[self performSelectorInBackground:@selector(aMethod) withObject:nil];
表示没有参数的方法。或类似的东西
[self performSelectorInBackground:@selector(otherMethodWithString:andData:) withObjects:string, data, nil];
如果您有参数。
答案 3 :(得分:1)
这是另一个例子,解释了如何执行后台队列并与其中的用户进行迭代。
- (void)method
{
// start a background proccess that will not block the UI
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i = 0; i < 1000000; i++) {
if (i == 999) {
// Need to iterate with interface elements when inside a background thread.
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Found" message:@"Found your number" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alertView show];
});
}
NSLog(@"Count: %d",i);
}
});
}
答案 4 :(得分:1)
正如其他人所指出的那样,使用GCD绝对是一个好方法。
或者,如果您希望操作可取消(例如加载Web资源),您可以考虑继承NSOperation
并检查isCancelled
。
(AFNetworking实际上是在制作/管理网络请求时执行此操作(例如AFHTTPRequestOperationManager
。)
查看NSOperation
和this tutorial on Ray Wenderlich's site上的Apple文档,了解有关NSOperation
的详细信息。