如何在不阻止UI的情况下重复调用方法?

时间:2014-02-14 20:57:21

标签: ios objective-c recursion nonblocking

非常通用的问题,有没有办法在不阻止UI加载的情况下调用我经常使用的方法?

5 个答案:

答案 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。)

查看NSOperationthis tutorial on Ray Wenderlich's site上的Apple文档,了解有关NSOperation的详细信息。