Ios Objective-C后台任务UIBackgroundTaskIdentifier重复

Ios Objective-C后台任务UIBackgroundTaskIdentifier重复,ios,objective-c,background-process,uiapplication,dispatch-async,Ios,Objective C,Background Process,Uiapplication,Dispatch Async,我有一个后台任务,在30分钟后停止拖缆,如下所示: - (void)applicationDidEnterBackground:(UIApplication *)application { bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ [[UIApplication sharedApplication] endBackgroundTask:bgTask];

我有一个后台任务,在30分钟后停止拖缆,如下所示:

- (void)applicationDidEnterBackground:(UIApplication *)application
{


bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
    [[UIApplication sharedApplication] endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    while ([[NSDate date] timeIntervalSinceDate:[[NSUserDefaults standardUserDefaults]objectForKey:@"date"]]<30) {
        NSLog(@"<30");

         [NSThread sleepForTimeInterval:1];


     }
    NSLog(@"Stop");
    [main stopStreaming];


 });
}
-(无效)应用程序标识符背景:(UIApplication*)应用程序
{
bgTask=[[UIApplication sharedApplication]beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication]endBackgroundTask:bgTask];
bgTask=UIBackgroundTaskInvalid;
}];
调度异步(调度获取全局队列(调度队列优先级默认为0)^{

而([[NSDate date]timeIntervalSinceDate:[[NSUserDefaults standardUserDefaults]objectForKey:@“date”]]您必须跟踪已启动的后台任务,并确保在新任务启动时不会执行以前的任务。您可以通过在应用程序代理中保留一个
NSInteger
并每次递增来轻松完成此任务

但更简单的方法是:(代替
dispatch\u async
调用)

这会将计时器设置为30秒,并确保之前的计时器未运行。然后只需在30秒后执行
-(void)dothis
即可执行任何您想要的操作


(您可能希望在30秒后签入
dothis以确认任务仍在后台,或者使用
cancelPreviousPerformRequestsWithTarget:…
ApplicationWilenterForeground:
中手动删除计时器)

如果(bgTask==UIBackgroundTaskInvalid)检查
如何…
在创建新的后台任务之前?这不会超过30秒的超时时间。回答很好,我一点也不认为选择器:withObject:afterDelay:会在后台工作。顺便问一句,如果我将时间设置为3小时,这种方法能保证工作吗?它不能保证工作3小时。它保证工作时间一样长s您有权在后台运行,这取决于操作系统,但通常会超过30秒。请注意,您可能还应该在过期处理程序中取消以前的PerformRequestswithTarget:…
,以避免在应用程序挂起后到达前台时让
DothisAfter30s
运行ed.它在后台工作的原因是,你的应用程序的非UI部分仍然像往常一样在后台运行。如果计时器停止工作,大量的东西将随之停止工作。据我从你那里了解,当你要求iOS在一段时间后控制应用程序时,iOS会获得我的许可
beginBackgroundTaskWithExpirationHandler:
,您将获得一个代表后台任务的数字。当iOS认为您有足够的时间时,它将调用处理程序,完成后将挂起您的应用程序。当用户切换到同样,应用程序可以从最后一点恢复,也可以从零开始(如果它已被杀死以重新获得资源)。如果计时器设置为在暂停点后触发,则会在应用程序恢复时触发。苹果的文档对此有更多说明。
SEL methodSelector = @selector(doThisAfter30Seconds);
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:methodSelector object:nil];
[self performSelector:methodSelector  withObject:nil afterDelay:30];