应用程序在后台时预定的NSTimer?

can*_*boy 54 iphone nstimer uiapplicationdelegate ios

当应用程序在后台时,人们如何处理预定的NSTimer?

假设我每小时在我的应用中更新一些内容.

updateTimer = [NSTimer scheduledTimerWithTimeInterval:60.0*60.0 
target:self 
selector:@selector(updateStuff) 
userInfo:nil 
repeats:YES];
Run Code Online (Sandbox Code Playgroud)

在后台时,此计时器显然不会触发(?).当用户回到应用程序时应该怎么办?计时器是否仍然在运行,同一时间?

如果用户在一小时内回来,会发生什么.它会在错过的所有时间触发,还是等到下一次更新时间?

我想要它做的是在应用程序进入前台后立即更新,如果它应该触发的日期是过去的.那可能吗?

Rob*_*ert 42

在后台执行模式下,您可以启动计时器.有几个技巧:

如果你在主线程上:

{
    // Declare the start of a background task
    // If you do not do this then the mainRunLoop will stop
    // firing when the application enters the background
    self.backgroundTaskIdentifier =
    [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{

        [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskIdentifier];
    }];

    // Make sure you end the background task when you no longer need background execution:
    // [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskIdentifier];

    [NSTimer scheduledTimerWithTimeInterval:0.5
                                     target:self
                                   selector:@selector(timerDidFire:)
                                   userInfo:nil
                                    repeats:YES];
}

- (void) timerDidFire:(NSTimer *)timer
{
    // This method might be called when the application is in the background.
    // Ensure you do not do anything that will trigger the GPU (e.g. animations)
    // See: http://developer.apple.com/library/ios/DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW47
}
Run Code Online (Sandbox Code Playgroud)

笔记

  • 应用程序仅在后台执行时间约10分钟(从iOS 7开始约3分钟) - 此后计时器将停止触发.
  • 从iOS 7开始,当设备被锁定时,它几乎会立即暂停前台应用程序.iOS 7应用程序锁定后,计时器不会启动.


Mac*_*n13 40

您不应该通过设置计时器来解决此问题,因为您不允许在后台执行任何代码.想象一下,如果用户在此期间或其他一些边缘情况下重启iPhone,会发生什么.

使用AppDelegate 的applicationDidEnterBackground:and和applicationWillEnterForeground:方法来获取所需的行为.它的功能更强大,因为当你的应用程序因重启或内存压力而被完全杀死时它也会起作用.

当应用程序进入后台时,您可以节省计时器下次触发的时间,并检查应用程序返回前台时是否应该采取措施.也可以在此方法中停止并启动计时器.在您的应用程序运行时,您可以使用计时器在适当的时刻触发更新.


小智 18

如果您或其他人正在寻找如何在Swift的后台运行NSTimer,请将以下内容添加到您的App Delegate:

var backgroundUpdateTask: UIBackgroundTaskIdentifier = 0


func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    return true
}

func applicationWillResignActive(application: UIApplication) {
    self.backgroundUpdateTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({
        self.endBackgroundUpdateTask()
    })
}

func endBackgroundUpdateTask() {
    UIApplication.sharedApplication().endBackgroundTask(self.backgroundUpdateTask)
    self.backgroundUpdateTask = UIBackgroundTaskInvalid
}

func applicationWillEnterForeground(application: UIApplication) {
    self.endBackgroundUpdateTask()
}
Run Code Online (Sandbox Code Playgroud)

干杯!

  • 这段代码应该做什么?它对我来说看起来像是无操作? (2认同)
  • 但计划的定时器在哪里? (2认同)

jba*_*100 6

在后台,这个计时器显然不会发射

这篇文章表明事情并不那么清楚.当应用程序进入后台时,您应该使计时器无效,并在它返回前台时重新启动它们.在后台运行东西可能是可能的,但是再次它可能会让你被杀...

您可以在此处找到有关iOS多任务处理方法的详细文档.

  • 链接断开:(( (2认同)

Enr*_*ini 6

在iOS 8上,当应用程序处于后台时(即使iphone被锁定),您可以通过简单的方式将NSTimer工作到最多约3分钟:

只需scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:像往常一样实现方法,你需要的地方.在AppDelegate内部创建一个属性:

UIBackgroundTaskIdentifier backgroundUpdateTask
Run Code Online (Sandbox Code Playgroud)

然后在你的appDelegate方法中:

- (void)applicationWillResignActive:(UIApplication *)application {
    self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
    [self endBackgroundUpdateTask];
    }];
}

- (void) endBackgroundUpdateTask
{
    [[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
    self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    [self endBackgroundUpdateTask];
}
Run Code Online (Sandbox Code Playgroud)

3分钟后计时器不会发射更多,当应用程序将在前台重新启动时,它将再次开始启动