14

我有一个我想-viewDidLoad在后台线程之后调用的方法。有没有办法结合这两种方法:

[self performSelector:(SEL) withObject:(id) afterDelay:(NSTimeInterval)]

[self performSelectorInBackground:(SEL) withObject:(id)]?

4

4 回答 4

23

Grand Central Dispatchdispatch_after()将在指定队列的指定时间后执行一个块。如果您创建一个后台队列,您将拥有您想要的功能。

dispatch_queue_t myBackgroundQ = dispatch_queue_create("com.romanHouse.backgroundDelay", NULL);
// Could also get a global queue; in this case, don't release it below.
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC);
dispatch_after(delay, myBackgroundQ, ^(void){
    [self delayedMethodWithObject:someObject];
});
dispatch_release(myBackgroundQ);
于 2012-06-22T19:06:28.300 回答
7

尝试以下操作:

// Run in the background, on the default priority queue
dispatch_async( dispatch_get_global_queue(0, 0), ^{
    [self performSelector:(SEL) withObject:(id) afterDelay:(NSTimeInterval)]
});

代码未测试

请注意,您的选择器/方法不得使用 UIKit(因此不要更新 UI)或访问 UIKit 属性(如框架),因此您的选择器可能需要将工作重新启动到主线程。例如

(id)SomeMethod:UsingParams: {

    // Do some work but the results

    // Run in the background, on the main queue
    dispatch_async(dispatch_get_main_queue(), ^{
        // Do something UIKit related
    });
}
于 2012-06-22T19:10:07.910 回答
4
[self performSelector:(SEL) withObject:(id) afterDelay:(NSTimeInterval)]

在被调用的线程上执行选择器。因此,当您从后台线程调用它时,它将在那里运行...

于 2012-06-22T19:00:07.870 回答
2

您可以按照示例执行此操作:

dispatch_time_t delay = dispatch_time( DISPATCH_TIME_NOW, <delay in seconds> * NSEC_PER_SEC );
dispatch_after( delay, dispatch_get_main_queue(), ^{
    [self performSelectorInBackground: <sel> withObject: <obj>]
});

不知何故混合解决方案。最好坚持使用完整的 GCD 方法。

于 2012-06-22T19:07:31.580 回答