使用Objective-C创建时间计数器

时间:2010-12-11 13:19:18

标签: objective-c

我是Objective-c的新东西,我正在尝试创建一个时间计数器,但是当我启动start方法时,更新方法只执行了一次,然后我进入控制台:

2010-12-11 14:11:45.080 StatusBarApp[10037:a0f] Break down: 0min 0hours 0days 0moths
Program received signal:  “EXC_BAD_ACCESS”.
sharedlibrary apply-load-rules all

我真的不明白问题出在哪里。 这是我的代码:

- (void)start:(id)sender {
     recordDate = [NSDate date];
     _timer = [NSTimer scheduledTimerWithTimeInterval:(1.0) target:self                 
     selector:@selector(updateTime:) userInfo:nil repeats:YES];
     [_timer fire];
 }


  - (void)stop:(id)sender {
       [statusItem setTitle:@""];
       [_timer invalidate];
           [_timer release];
}
   - (IBAction)updateTime:(id)sender {
    // The time interval 

    // Get the system calendar
    NSCalendar *sysCalendar = [NSCalendar currentCalendar];

    // Create the NSDates
    NSDate* date1 = [[NSDate alloc] init];
    // Get conversion to months, days, hours, minutes
    unsigned int flags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSDayCalendarUnit |   NSMonthCalendarUnit;
     NSDateComponents* breakdownInfo = [sysCalendar components:flags fromDate:date1   toDate:recordDate  options:0];
     NSLog(@"Break down: %dmin %dhours %ddays %dmoths",[breakdownInfo minute],  [breakdownInfo hour], [breakdownInfo day], [breakdownInfo month]);
     [date1 release];
     [statusItem setTitle:[NSString stringWithFormat:@" %dmin %dhours %ddays  %dmoths",[breakdownInfo minute], [breakdownInfo hour], [breakdownInfo day], [breakdownInfo month]]];
   }

1 个答案:

答案 0 :(得分:2)

您的问题是[NSDate date]会返回自动发布的日期。这适用于计时器的第一次运行,因为在fire初始化的方法结束之前,您在计时器上调用recordDate

你需要retain recordDate才能活得足够长,以便在随后的计时器点击中继续使用它。

在每次运行循环迭代结束时,框架将释放自动释放的对象。您永远无法可靠地知道运行循环何时结束,因此您只能安全地假设自动释放的对象可以安全地使用,直到它们被自动释放的方法结束。

在您的代码中添加recordDate = [[NSDate date] retain];可以解决您的问题。

但是不要忘记,现在你保留了recordDate对象,你需要在将来的某个时候发布它 - 在stop:方法中看起来像是一个很好的地方

最后,在释放recordDate对象后,您应该将nil指定给指针以防止任何“悬空指针”问题。