在后台运行的任务不会触发委托

时间:2012-01-18 15:16:17

标签: objective-c ios4 delegates background

我对iOS开发和objC都很陌生,所以请光临我......

我的应用程序必须轮询服务器最多10分钟(使用RestKit),即使应用程序被发送到后台也是如此。 (轮询始终在应用程序位于前台时启动)

我有一个监听applicationDidEnterBackground的View Controller(不是RootViewController)。

此外,还有一个“Order”类,它有一个方法“poll”,用于向服务器发送请求,以及其他几个回调方法,用于“超时”,“请求取消”,“处理响应”等。

- (void)poll
{
    RKRequest* request = [[RKClient sharedClient] requestWithResourcePath:@"/foo.php" delegate:self];
request.backgroundPolicy = RKRequestBackgroundPolicyContinue;    
[request send];    

NSLog(@"I am your RKClient singleton : %@", [RKClient sharedClient]);        
}
- (void)requestDidStartLoad:(RKRequest *)request {
NSLog(@"requestDidStartLoad");
}
- (void)requestDidTimeout:(RKRequest *)request {
NSLog(@"requestDidTimeout");
}
- (void)request:(RKRequest *)request didFailLoadWithError:(NSError *)error {
NSLog(@"didFailLoadWithError");
}
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response 
{  
}

当应用程序处于前台时,一切正常,并且会触发回调。

当我的应用程序进入后台时,我想继续轮询服务器。我使用这种方法,调用“poll”,但没有触发回调..

- (void)applicationDidEnterBackground:(NSNotification *) notification 
{
Order *order = [[Order alloc] init];

UIApplication *app = [UIApplication sharedApplication];

__block UIBackgroundTaskIdentifier taskId;

taskId = [app beginBackgroundTaskWithExpirationHandler:^{    
    [app endBackgroundTask:taskId]; 
}];

if (taskId == UIBackgroundTaskInvalid) { 
    return;
}

dispatch_async(dispatch_get_global_queue(0, 0), ^{ 

    while(YES)
    {
        sleep(1);

        [order poll];
    }

    [app endBackgroundTask:taskId]; 
});

[order release];

}

我做错了什么?

谢谢!

1 个答案:

答案 0 :(得分:1)

我不知道您正在使用的这个RKClient,但可能它基于NSURLConnection API。只有在运行循环内运行时,此异步API才会调用委托;来自NSURLConnection文档:

Messages to the delegate will be sent on the thread that calls this method. For the connection to work correctly the calling thread’s run loop must be operating in the default run loop mode.

不幸的是,GCD不保证你在执行运行循环的线程中运行一个块。在这种情况下的建议是你在NSOperation中运行你的“民意调查”,这是针对这种情况进行优化的。