Iphone 节省时间';进入后台并在前台检索时,是到磁盘的时间

Iphone 节省时间';进入后台并在前台检索时,是到磁盘的时间,iphone,ios,objective-c,background,nstimer,Iphone,Ios,Objective C,Background,Nstimer,我想让我的计时器在后台工作,我已经找到了真正做到这一点的唯一方法,那就是在applicationdidenterbackground上节省时间,并使用applicationidlaunchwithoptions检索它。my timer使用核心数据,我的时间间隔(testTask.timeInterval)在每次递减后都会保存,因此: -(IBAction)startTimer:(id)sender{ if (timer == nil) { [startButton set

我想让我的计时器在后台工作,我已经找到了真正做到这一点的唯一方法,那就是在
applicationdidenterbackground
上节省时间,并使用
applicationidlaunchwithoptions检索它。
my timer使用核心数据,我的时间间隔(testTask.timeInterval)在每次递减后都会保存,因此:

-(IBAction)startTimer:(id)sender{
    if (timer == nil) {
        [startButton setTitle:@"Pause" forState:UIControlStateNormal];
       timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
    } else {
        [startButton setTitle:@"Resume" forState:UIControlStateNormal];
        [timer invalidate];
        timer = nil;
    }

}
-(void)timerAction:(NSTimer *)t
{
    if(testTask.timeInterval == 0)
    {
        if (self.timer)
        {
            [self timerExpired];
            [self.timer invalidate];
            self.timer = nil;
        }
    }
    else
    {
        testTask.timeInterval--;
        NSError *error;
        if (![self.context save:&error]) {
            NSLog(@"couldn't save: %@", [error localizedDescription]);
        }
    }
    NSUInteger seconds = (NSUInteger)round(testTask.timeInterval);
    NSString *string = [NSString stringWithFormat:@"%02u:%02u:%02u",
                        seconds / 3600, (seconds / 60) % 60, seconds % 60];
    timerLabel.text = string;
    NSLog(@"%f", testTask.timeInterval);
}
-(void)timerExpired{
    UILocalNotification* localNotification = [[UILocalNotification alloc] init];
    localNotification.alertBody = @"Time is up";
    localNotification.alertAction = @"Ok";
    localNotification.timeZone = [NSTimeZone defaultTimeZone];
    [[UIApplication sharedApplication]presentLocalNotificationNow:localNotification];
}
这些方法位于详图视图控制器中,该控制器通过以下方式初始化:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    DetailViewController *detailVC;
    if (![self.detailViewsDictionary.allKeys containsObject:indexPath]){
        detailVC = [[DetailViewController alloc]initWithNibName:@"DetailViewController" bundle:nil];
        [self.detailViewsDictionary setObject:detailVC forKey:indexPath];
        detailVC.context = self.managedObjectContext;
    }else{
        detailVC = self.detailViewsDictionary[indexPath];
    }
        Tasks *task = [[self fetchedResultsController] objectAtIndexPath:indexPath];
        detailVC.testTask = task;
        [[self navigationController] pushViewController:detailVC animated:YES];
    NSLog(@"%@", self.detailViewsDictionary);
}

我不明白的是…如何访问时间间隔(每个detailviewcontroller都有不同的时间间隔…),以便将其放入
AppliationDiEnterBackground
?另外,我猜我应该节省应用程序进入后台的时间,然后节省进入前台的时间,然后减去?然后我会从时间间隔中减去这个值,对吗?

首先,如果你关心精度的话,就不应该使用这样的直接倒计时。
NSTimer
不会在精确的1秒间隔内触发,延迟会累积。更好的方法是在计时器启动时创建一个
NSDate
,然后在每个滴答声处获取此后的
NSTimeInterval
,然后计算分钟和秒数

对于每个要存储其自己的开始时间的视图控制器,您可以注册任何对象以接收。这是在应用程序代理获取
ApplicationIdentinterBackground:
的同时发布的

另外,我猜我应该节省应用程序进入后台的时间,然后节省进入前台的时间,然后减去?然后我会从时间间隔中减去这个值,对吗

是的:


将为您提供计时器经过的活动时间。

我对第一部分有点困惑。如果我在计时器启动时创建NSDate,我应该在timerAction方法中将其与什么进行比较,以确保计时器按原样工作?
[[NSDate date]timeIntervalSinceDate:timerStartDate]
NSTimeInterval idleTime = [dateReturnedToForeground timeIntervalSinceDate:dateEnteredBackground];
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:startDate];
elapsedTime -= idleTime;