2011-02-17 62 views
1

我正在嘗試創建一個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

回答

2

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

  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