EXC_BAD_ACCESS从NSTimer调用函数

时间:2011-09-07 18:58:38

标签: objective-c cocoa

我不得不说,我对Objective-c / Cocoa很新。目前我正在尝试使用NSTimer定期更新一些数据。

@interface MyAppController : NSObject  
{
    NSTimer * monitorTimer;
    DemoObject *myObj;
}
...

以及以下实施:

...
- (id) init
{
    self = [super init];

    if (self) {
        myObj = [[DemoObject alloc] init];

        monitorTimer = [NSTimer timerWithTimeInterval:2
                                               target:self
                                             selector:@selector(monitorTimerFired:) 
                                             userInfo:NULL 
                                              repeats:YES];

        [[NSRunLoop currentRunLoop] addTimer:monitorTimer forMode:NSDefaultRunLoopMode];
    }

    return self;
}

...

- (void) monitorTimerFired: (id)sender
{               
    BOOL status = [myObj isRunning];
}

同步调用monitorTimerFired,例如,从init函数调用。如果它被计时器调用,它总是会产生EXC_BAD_ACCESS。显然这是内存管理的问题,但我找不到合适的解决方案。任何想法,评论,解决方案?谢谢:))

2 个答案:

答案 0 :(得分:5)

如果要将NSTimer存储在实例变量monitorTimer中,则应该在完成后保留并正确地使其无效,释放和nil(如果不是dealloc)。< / p>

monitorTimer = [[NSTimer timerWithTimeInterval:2
                                        target:self
                                      selector:@selector(monitorTimerFired:) 
                                      userInfo:NULL 
                                       repeats:YES] retain];

对于EXC_BAD_ACCESS,您的MyAppController可能会在计时器触发时释放。

答案 1 :(得分:1)

我建议将monitorTimer实例变量更改为属性,例如:

@property (nonatomic, retain) NSTimer *monitorTimer;

这样,当您在将来尝试更改monitorTimer时,会为您完成正确的mem-mgmt - 只需通过self.monitorTimer = ...使用合成的设定器。
好吧,不要忘记在-dealloc方法中正确释放它。通过调用[monitorTimer invalidate]来释放计时器之前停止计时器。

说到停止计时器:在你的init方法中你设置你的计时器重复,所以当你不再需要它时,请确保你停止它(特别是在-dealloc如上所述!)。