2010-05-07 85 views
0

我有一個問題,似乎只發生在設備上,而不是在模擬器中。iPhone NSTimer OpenGL問題

我的應用程序的動畫開始和使用這些方法停止:

NSTimer* animationTimer; 

-(void)startAnimation 
{ 
    if(animationTimer == nil) 
     animationTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f/60.0f target:self selector:@selector(drawView) userInfo:nil repeats:YES]; 
} 

-(void)stopAnimation 
{ 
    [animationTimer invalidate]; 
    animationTimer = nil; 
} 

在此工作正常,並開始drawView函數以60fps被稱爲仿真器。 在設備上(在iPod Touch上測試),scheduleTimerWithTimeInterval方法似乎不起作用。此外,[animationTimer invalidate]導致EXC_BAD_ACCESS。

我發現了一個顯而易見的小缺陷;如果(animationTimer!= nil)添加到stopAnimation方法將防止崩潰,但不能解決動畫計時器未正確初始化的問題。

編輯:以上不防止崩潰。 animationTimer!=零,但調用invalidate會導致EXC_BAD_ACCESS。

還應該加上,這個問題在設備上不會一直髮生。也許40%的時間。

+1

你的代碼真的說:'if(animationTimer = nil)' – drawnonward 2010-05-07 08:59:20

+0

不,更新。謝謝。 – Tobster 2010-05-07 16:14:09

回答

0

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

請記住,NSTimer並不總是「準時」啓動。您的應用程序可以在模擬器上運行,因爲它擁有大量可用資源 - 幾乎可以在Mac上使用整個處理器和RAM。另一方面,該設備具有有限的可用資源。這可能會導致您的應用程序出現某種競爭狀態。

另一件事是你沒有保留計時器(這是一件好事),所以聲稱擁有它的唯一對象是你當前的運行循環。當你調用[timer invalidate];計時器被釋放。很有可能你的定時器被[timer invalidate]釋放到別的地方;功能。試圖使已經失效的計時器失效將導致一個符合你的描述的錯誤。

總體而言,請查看您的代碼,查看您的計時器可能已失效的其他地方。檢查競賽條件。

希望這是有幫助的, 保羅

+0

感謝您的回覆。 我可以確認這些是訪問定時器的唯一兩種方法,通過將其實例名更改爲animTimer並修復兩個構建錯誤進行確認。 我並不擔心計時器的準確性,因此它不是特別苛刻的應用程序。目前它是全部(60fps)或者什麼都沒有(drawView只是不被調用,就好像NSTimer從未被實例化過)。 – Tobster 2010-05-07 09:11:00

3

如果animationTimer是完全一樣的,你已經證明聲明,那麼它的初始值是不確定的。傳遞一個不對應於分配的Objective-C對象的指針值很可能會給你帶來EXC_BAD_ACCESS。您應該明確地將其初始值設置爲nil,或者考慮將其聲明爲您類的成員變量,以便在分配對象時將其初始化爲0/nil和其他成員變量。

+0

已經在代碼corectness的構造函數中實現了animationTimer = nil,但它沒有解決問題。 [NSTimer scheduleTimerWithTimeInterval:]行正在執行,但這似乎並不是每次都在設備上工作。 – Tobster 2010-05-10 10:29:52