天道酬勤,学无止境

NSTimer crashes with bad access

I have the following method to update a label which show a simple time up

-(void)updateTimeLabel:(NSTimer *)timer{
    NSInteger secondsSinceStart = (NSInteger)[[NSDate date] timeIntervalSinceDate:_startTime];

    NSInteger seconds = secondsSinceStart % 60;
    NSInteger minutes = (secondsSinceStart / 60) % 60;
    NSInteger hours = secondsSinceStart / (60 * 60);
    NSString *result = nil;
    if (hours > 0) {
        result = [NSString stringWithFormat:@"%02d:%02d:%02d", hours, minutes, seconds];
    }
    else {
    result = [NSString stringWithFormat:@"%02d:%02d", minutes, seconds];
    }

    _totalTime = result;
    _totalTimeLabel.text = result;
}

I then call this as the action to a button:

-(IBAction) startTimer{
    _startTime = [NSDate date];
    _walkRouteTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateTimeLabel:) userInfo:nil repeats:YES];
    [_walkRouteTimer fire];
}

But when I run the app I get a bad access error and the app crashes, can anyone help me with this?

Thanks in advance

评论

Are you using ARC? If not, _startTime = [NSDate date]; this line will cause your problem. [NSDate date] returned an autorelease object and _startTime will not hold it if you are not using ARC(or using ARC but declared _startTime as weak).

If so, try to add a retain to it

-(IBAction) startTimer{
    //_startTime = [NSDate date]
    _startTime = [[NSDate date] retain];
    _walkRouteTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateTimeLabel:) userInfo:nil repeats:YES];
    [_walkRouteTimer fire];
}

And when you finished your timer, after calling of [_walkRouteTimer invalidate], call [_startTime release].

Or even simpler, if you use property for startTime and declared it as retain. Just use dot notation:

-(IBAction) startTimer{
    //_startTime = [NSDate date]
    self.startTime = [NSDate date];
    _walkRouteTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateTimeLabel:) userInfo:nil repeats:YES];
    [_walkRouteTimer fire];
}
...
//After [_walkRouteTimer invalidate]
self.startTime = nil;

Try adding an exception breakpoint to see which line is crashing:

1) Click on the breakpoint tab (second from the right)... kinda looks like a right pointing arrow or "next" button

2) Click on the "+" in the bottom left corner of the tab menu

3) Select "Add Exception Breakpoint"

4) (Optional) Select "Exception" drop down and change to "Objective-C"

5) Select "Done"

6) Run your code again and try to generate the crash... when you do, it will hopefully be caught by this breakpoint, and you'll see which line is crashing and be able to fix it

Good luck

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐