gpt4 book ai didi

iphone - 使用多个 beginBackgroundTaskWithExpirationHandler 调用

转载 作者:行者123 更新时间:2023-12-03 20:28:09 25 4
gpt4 key购买 nike

我试图在这里关注之前的帖子:Best practice to send a lot of data in background on iOS4 device?

基本上,我有一个名为 getRequest 的方法,可以从 Web 服务器获取信息。我需要从网络服务器获取大约 50 条数据。因此,同时,我有 50 个对 connectionDidFinishLoading 的委托(delegate)调用。目前我的 getRequest 看起来像:

-(void) getRequestWithURL:(NSString *) requestURL 
{
static int getRequest = 0;
NSLog(@"getRequest: %i", getRequest);
getRequest++;

UIApplication *app = [UIApplication sharedApplication];
__block UIBackgroundTaskIdentifier taskID;
taskID = [app beginBackgroundTaskWithExpirationHandler:^{

NSLog(@"Time remaining: %f", app.backgroundTimeRemaining);

NSLog(@"Background task not completed");
[app endBackgroundTask:taskID];
}];

NSURLRequest *req = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:requestURL]];
NSURLConnection *con = [[NSURLConnection alloc] initWithRequest:req delegate:self] ;
[self startRequestWithConnection:con];
[req release];

if (taskID == UIBackgroundTaskInvalid) {
NSLog(@"Failed to create background task identifier");
}

}

然后在我的连接中DidFinishLoading:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// process data from server
// endBackgroundTask:someTaskID???
}

我知道您可以多次调用 beginBackgroundTaskWithExpirationHandler,但我不知道我在 getRequest 方法中所做的是否是这样做,因为我只有一个变量 __block UIBackgroundTaskIdentifier taskID每次调用该方法时。而且我也不确定是否需要在每次调用 getRequest 时在 connectionDidFinishLoading 方法中调用 endBackgroundTask,因为您应该平衡 beginBackgroundTaskWithExpirationHandler 与 endBackgroundTask: 调用。如果是这样,由于我的 getRequest 目前没有该基础设施,我该怎么做?我是否需要 50 个 ivars 才能让 connectionDidFinishLoading 方法看到对 getRequest 的 50 次初始调用?谢谢。

最佳答案

正如您所说,您需要平衡 beginBackgroundTaskWithExpirationHandler 调用与 endBackgroundTask 调用。

我想到的一个解决方案如下所示:

创建一个新的实例变量

UIBackgroundTaskIdentifier backgroundTaskID;

无论如何,您都会对请求进行计数,因此您也可以减少connectionDidFinishLoading中的getRequest:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// process data from server
getRequest--;

if (getRequest == 0 && backgroundTaskID != UIBackgroundTaskInvalid)
{
[[UIApplication sharedApplication] endBackgroundTask:backgroundTaskID];
backgroundTaskID = UIBackgroundTaskInvalid;
}
}

现在,后台任务在最后一个请求完成后结束。要仅启动一个后台任务,您可以在应用程序转到后台时调用的方法中启动它。

您需要监听UIApplicationDidEnterBackgroundNotification

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidEnterBackground)
name:UIApplicationDidEnterBackgroundNotification
object:nil];

并实现该方法

- (void)applicationDidEnterBackground:(NSNotification *)notification
{
if (getRequest > 0) {
backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:backgroundTaskID];
backgroundTaskID = UIBackgroundTaskInvalid;
}];
}
}

现在,您只有一个正在运行的后台任务,该任务会在您的应用进入后台时自动启动,并且您正在运行的请求会在所有请求完成后结束。

另一个改进是将网络请求添加到 NSOperationQueue 中,以避免手动计数并限制并发请求的数量。

关于iphone - 使用多个 beginBackgroundTaskWithExpirationHandler 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9659410/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com