Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/113.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios NSTimer在背景/前景上的行为_Ios_Iphone_Objective C_Nstimer - Fatal编程技术网

Ios NSTimer在背景/前景上的行为

Ios NSTimer在背景/前景上的行为,ios,iphone,objective-c,nstimer,Ios,Iphone,Objective C,Nstimer,情况是: 应用程序的主运行循环每5分钟运行一次。当应用程序处于后台时,计时器不会失效 在前台等待一段时间(比如10分钟)后,计时器立即启动两次。我不清楚这里定义的行为应该是什么(如果有的话),除了在后台,计时器与应用程序一起暂停/挂起 在我看来,当应用程序前景化时,计时器实际上会查看从后台开始经过的时间,确定在这段时间内它应该触发的次数,然后全部触发。我在iOS 7模拟器和iOS 7 iphone上都观察到了这种情况 谷歌搜索在这个话题上没有找到太多的信息。有什么想法/建议吗 更新:澄清-我的问

情况是:

应用程序的主运行循环每5分钟运行一次。当应用程序处于后台时,计时器不会失效

在前台等待一段时间(比如10分钟)后,计时器立即启动两次。我不清楚这里定义的行为应该是什么(如果有的话),除了在后台,计时器与应用程序一起暂停/挂起

在我看来,当应用程序前景化时,计时器实际上会查看从后台开始经过的时间,确定在这段时间内它应该触发的次数,然后全部触发。我在iOS 7模拟器和iOS 7 iphone上都观察到了这种情况

谷歌搜索在这个话题上没有找到太多的信息。有什么想法/建议吗

更新:澄清-我的问题是,假设计时器在后台未失效/nil,并且未在前台创建新的计时器,则应用程序在后台,然后再次前景化时,NSTimer的行为是什么

代码示例(代码有点旧-弧前天数):

此处或处理此计时器的应用程序委托中都没有后台/前台处理程序

在我看来,当应用程序前景化时,计时器实际上会查看从后台开始经过的时间,确定在这段时间内它应该触发的次数,然后全部触发。我在iOS 7模拟器和iOS 7 iphone上都观察到了这种情况


这是对NSTimer和运行循环行为的正确描述。当你的应用程序被挂起时,它不会启动(默认情况下,当你将其设置为后台时;但如果你启动后台任务,它将在任务运行时正常启动)。

我不清楚这个问题。当应用程序出现在前台时,你是否启动新计时器?你确定是同一个计时器触发的吗?也许您可以发布代码,其他人会很清楚。NSTimer不能保证在后台启动。您可以对当前设置进行独立的时间检查,以确保fireFunction不会被背对背调用。再看看前面的问答,我意识到获得确定性行为的方法是在后台使计时器无效,然后在前台重新启动。我的问题是,背景/前景上的行为是记录在案的/已知的,还是未定义的。我的搜索似乎表明未定义,并且我没有找到任何相反的证据。您的回答是正确的,但“确定了在这两次搜索之间应该触发的次数,并且所有触发次数都与NSTimer文档中描述的不同:”如果点火时间延迟到超过一个或多个预定点火时间,则定时器在该时间段内仅点火一次;定时器在发射后会被重新安排在未来的下一个预定发射时间”,它会立即发射,但只发射一次。
@implementation ReportHandler {
    NSTimer *_reportTimer;
}

- (id)init
{
    if (_reportTimer == nil) {
        _reportTimer = [[NSTimer  timerWithTimeInterval:5*60 target:self selector:@selector(didFireReportTimer:) userInfo:nil repeats:YES] retain];
        [[NSRunLoop mainRunLoop] addTimer:_reportTimer forMode:NSDefaultRunLoopMode];
    }
}

- (void)didFireReportTimer:(NSTimer *)timer {
   // send report over network here, timer is not invalidated here
}