NSTimer访问不好

时间:2011-02-17 06:24:32

标签: crash nstimer retain

我正在尝试创建一个NSTimer,然后使其无效并释放它,然后将其设置为新的计时器。但是,在尝试再次设置计时器成员var时,我得到一个EXC_BAD_ACCESS。

以下代码:

1)我设置了计时器成员var(它设置为保留)

self.mPageTimer = [NSTimer scheduledTimerWithTimeInterval:kPageTimerInterval target:self selector:@selector(pageTimerCallback) userInfo:nil repeats:NO];

2)我放手了

    [mPageTimer invalidate];
    [mPageTimer release];

当我再次尝试在步骤1中调用代码段时,会导致崩溃,但我不确定原因。我通过设置它来保留它,然后我释放它,所以不应该处理对象并且我的成员可以设置为新的分配计时器吗?

如果我这样做,它不会崩溃并且工作正常:

    [mPageTimer invalidate];
    [mPageTimer release];
    mPageTimer = nil;

我无法看到我在释放对象时做错了什么,因为无论是否是这种情况,我都不应该总是将我的成员var设置为新创建的nstimer,leak或者不?

1 个答案:

答案 0 :(得分:2)

可以安全地假设......

  1. 代码段2)来自@property的设置者,但来自另一种方法
  2. 只需@synthesize mPageTimer
  3. 计时器的声明是@property (nonatomic, retain) NSTimer* mPageTimer
    (无论是非原子的还是原子的都无关紧要)
  4. 如果是这种情况,则预计会发生崩溃:

    create timer (timer retains you, timer is autoreleased!)
    schedule timer (runloop retains the timer)
    assignment through setter (you retain the timer)
    ... (time passes)
    has it fired?
    Yes:
        since your timer is non-recurring, the runloop has marked it
        as invalid and released it after invocation of "pageTimerCallback:"
    calling "invalidate":
        has it fired?
        No:
            runloop unschedules and releases
        Yes:
            noop or release (read: "I don't know and admittedly don't care")
    calling "release" (you are no longer the owner)
    ... (time passes)
    assignment through synthesized setter:
        [newTimer retain];
        [oldTimer release]; // Crash due to overrelease!
    

    简而言之:
    如果您拥有计时器的属性,提供您自己的设置器并让每次访问都使用它
    (允许两个例外:1。执行setter 2.在dealloc中你release计时器*)

    (*不要使你成为dealloc目标的计时器失效:It is absolutely pointless!)