NSTimer坏访问

问题描述:

我正在尝试创建一个NSTimer,然后使其无效并释放它,然后将其设置为新的计时器。但是,在尝试再次设置计时器成员变量时,我正在获取EXC_BAD_ACCESS。下面NSTimer坏访问

代码:

1)I设置定时器成员VAR(它被设置为保留)

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

2)我让他走

[mPageTimer invalidate]; 
    [mPageTimer release]; 

这将导致崩溃当我尝试再次在第1步中调用片段时,但我不确定原因。我保留它,然后我释放它,所以不应该照顾对象,我的成员var ok可以设置为一个新的分配的计时器?

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

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

我不能看到我是如何做的一些错误释放的对象,因为,无论如果是这样的情况下,我应该不能总是将我的成员var设置为新创建的nstimer,泄漏或不是?

+0

检查你的代码中的任何其他地方,你在'release'之后将消息传递给`mPageTimer`。因为你可以将消息传递给`nil`,所以它可能不会崩溃。 – Mahesh 2011-02-17 06:35:41

它是安全的假设,即...

  1. 片段2)@property的二传手,但是从另一种方法
  2. 简单@synthesize mPageTimer
  3. 定时器的声明是@property (nonatomic, retain) NSTimer* mPageTimer
    (是否非原子或原子无所谓)

如果是这样的话,你的崩溃预计:

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的dealloc实现二传手2.你在哪里release计时器*)

(*不坏,你是在dealloc的目标定时器:It is absolutely pointless

+0

你在上面的3个假设中是正确的。从阅读你的文章和你的链接,我可以收集,因为runloop保留我的计时器,而不是写一个setter,我可以声明它分配和不保留,然后使用调用作为中断/关闭手段失效 - 在火灾发生之前放下计时器?这意味着我会用scheduledTimerWithTimeInterval创建它,而不需要调用release,对吧? – Joey 2011-02-17 19:17:56