2010-03-15 91 views
1

viewWillAppear安排與的NSTimer的功能的計時器如下更快:用的NSTimer日程定時使得任務運行比預期

minutesTimer = nil; 
minutesTimer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(updateScrollViewItems) userInfo:NULL repeats:YES]; 

通過調用該功能,我希望它來調用選擇updateScrollViewItems每一分鐘,但它沒有,它更新項目比預期更快(大約幾秒鐘)。

這種意外行爲的原因是什麼?

回答

5

它可能不是你所看到的問題的直接原因,但我已經可以發現一個重大錯誤。

每次在viewWillAppear上設置此計時器的事實意味着,無論何時出現您的視圖,您都會創建一個新計時器(並泄漏舊計時器),該計時器將在創建後啓動60秒。

如果您的視圖消失並重復出現多次,那麼您將有多個定時器以完全隨機的間隔發射相同的方法。

您需要正確管理計時器。如果您希望在視圖第一次創建時啓動視圖,並且即使未顯示視圖時也保持滴答/啓動,則需要在initviewDidLoad期間創建該視圖,然後當您使用deallocviewDidUnload時一定要停止它。

如果您希望您的計時器只在當前視圖顯示時打勾/觸發,那麼您需要確保您正在管理停止並在viewDidAppearviewWillDisappear之間正確啓動計時器。

此外,正如Williham Totland在他的回答中所說,NSTimer不應該依賴於確切的時間。這也在文檔中說明:

定時器不是實時機制;只有在添加了定時器的運行循環模式之一運行並且能夠檢查定時器的觸發時間是否已過時,它纔會觸發。由於典型的運行循環管理各種輸入源,所以定時器的時間間隔的有效分辨率被限制在50-100毫秒的量級上。如果在運行循環處於未監視定時器的模式下或在長時間標註期間發生定時器的觸發時間,則定時器將在下次運行循環檢查定時器時才觸發。因此,計時器觸發的實際時間可能是計劃的點火時間之後的相當長的一段時間。

在這種情況下,用60秒的時間跨度,它不應該是定時不準確的問題,我認爲你所看到的問題是,因爲計時器沒有被妥善管理。

+0

感謝您指出問題,在將[timer invalidate]移動到viewdiddisappear方法時,我遇到了exc_bad_access問題的疑難解答。 (我已經將定時器的另一個init函數移到了viewDidLoad中,正如你所建議的那樣)。 – 2010-03-15 14:47:42

+1

如果您在'viewDidLoad'中創建了計時器,那麼您應該在'dealloc'或'viewDidUnload'中使其無效,而不是'viewDidDisappear'。每次你的視圖消失時,你將停止並釋放計時器對象,並且因爲它沒有被重新創建('viewDidLoad'只在視圖加載時被調用,而不是每當視圖出現在屏幕上時),你過度釋放它,導致訪問不良。 當您使用'scheduledTimer ...'創建一個計時器時,它會返回一個由runloop保留的計時器對象。當定時器發送'invalidate'時,它將從runloop中被移除並被釋放。 – Jasarien 2010-03-15 15:08:22

+0

哦,謝謝Jasarien,我已經解決了這個問題!我把計時器放在viewDidAppear中,並使其在viewDidDisappear中無效。 exc_bad_access infact來自其他xml解析器變量。感謝您的提示! – 2010-03-15 16:13:17

0

iPhone是很多東西;和一個整潔的設備,但是;就像任何其他電腦一樣,精密時計並非如此。但是,看起來好像這個方法需要一個NSTimeInterval,它是一個雙精度值。您可能需要將其更改爲60.0

0

如果你希望你的計時器只 週期/火的時候認爲是當前 觀點,那麼你需要確保你 管理停車和viewDidAppear 和viewWillDisappear適當地啓動 計時器。

感謝這個信息,即使我不是這個線程的OP,我正在尋找類似問題的答案。我撓了腦袋幾天,在互聯網上搜索,但我找不到答案。最後我找到了這個線程。這對我來說是一個有價值的信息。