2011-07-14 63 views
1

首先,我知道有一些關於此主題的其他StackOverflow問題,但我已經閱讀了所有這些問題,我仍然對如何處理我的情況感到困惑。我可能在這裏錯過了一些顯而易見的東西,如果你能幫助澄清一下,我們將非常感謝!重複NSTimer鎖UI線程

我有一個應用程序,它在視圖內爲圖像添加動畫做了很多工作 - 主要包括一次以直線移動一個或多個圖像的大量圖像。我首先考慮的是讓它們變得簡單,一旦在整個移動過程中使用UIView animateWithDuration關閉動畫。但是我發現這並沒有給我很大的力量來攔截這個動作或者阻止它或者檢查它到底在哪裏,所以我放棄了這個動作。我的新方法是使用NSTimer,每秒發射20次,做增量運動。這種方式我也可以立即干預(幾乎)立即改變動畫或停止它或更新狀態標籤,基於它是多遠,等等等等。

首先...有可能有更好的方法比這個。隨意建議更好的東西!

雖然這是可以接受的,但現在我的問題是,當這些動畫發生時,我無法點擊UI上的任何其他控件。我沒有得到任何迴應。它不像它只是緩慢或延遲 - 點擊從來沒有通過。看來NSTimer處理完全鎖定了用戶界面 - 但僅僅來自新的交互。我在定時器處理方法中對UI做出的更改發生得很好,而且非常活潑。

從我讀過的這個應該不會發生。不過,我也看到this question的評論說,如果定時器處理密集,然後它可能鎖定UI線程。我沒有看到我的處理在這裏是密集的 - 當然沒有資源請求,只是一些數據操縱和動畫的一些對象 - 但我可能會掩蓋它。

我在這裏有什麼選擇?起初我想我可能會創建一個新線程來啓動計時器。但我記得讀過,UI更新必須在主線程上發生。爲什麼是這樣?此外,這真的能解決問題嗎?我只是問太多的設備來處理這個計時器以及UI交互?還有什麼我失蹤?

任何和所有的意見,將不勝感激。

編輯:

我剛剛發現我的UI阻塞問題的原因。我正在使用帶有塊的animateWithDuration,但沒有設置選項。因此UIViewAnimationOptionAllowUserInteraction未設置。我改變它設置這個選項,我的用戶界面現在很高興地迴應。

這就是說,我仍然會留下這個問題,針對我的整體方法提出具體建議。謝謝。

回答

0

我會考慮使用CADisplayLink。從文檔:

CADisplayLink對象是一個計時器對象,它允許您的應用程序將其繪圖與顯示刷新率同步。

您的應用程序會創建一個新的顯示鏈接,提供一個目標對象和一個在屏幕更新時調用的選擇器。接下來,您的應用程序將顯示鏈接添加到運行循環中。

一旦顯示鏈接與運行循環相關聯,當屏幕內容需要更新時,將調用目標上的選擇器。目標可以讀取顯示鏈接的timestamp屬性以檢索顯示前一幀的時間。例如,顯示電影的應用程序可能會使用時間戳來計算下一個要顯示的視頻幀。執行自己的動畫的應用程序可能會使用時間戳來確定顯示的對象在即將到來的幀中的顯示位置和方式。持續時間屬性提供了幀之間的時間量。您可以在應用程序中使用此值來計算顯示器的幀速率,下一幀將顯示的大致時間,並調整繪製行爲,以便及時準備下一幀以供顯示。

您的應用程序可以通過將paused屬性設置爲YES來禁用通知。另外,如果您的應用程序無法在所提供的時間內提供幀,您可能需要選擇較慢的幀速率。與跳過幀的應用程序相比,具有較慢但一致幀頻的應用程序對用戶來說會更平滑。您可以通過更改frameInterval屬性來增加幀之間的時間(並降低明顯的幀速率)。

當您的應用程序使用顯示鏈接完成時,它應該調用invalidate從所有運行循環中將其刪除,並將其從目標中解除關聯。

CADisplayLink不應該被分類。

0

我並不完全確定在程序中如何處理所有內容,但您可能只想考慮讓一個線程/定時器控制所有對象及其移動。實際上不需要爲每個對象創建單獨的線程/定時器,因爲這很容易導致問題。

您可以使用包含有關其方向,速度,持續時間等信息的移動項目創建一個類,然後讓控制線程/計時器計算並移動對象。然後,您可以介入一個主控制器對象,而不必處理許多其他對象。

+0

對不起,也許我誤導了你。我只有一個計時器來控制所有的物體和它們的運動 - 這幾乎是你描述的。我認爲即使這可能不是最好的方法。無論如何,關於這與如何鎖定UI的問題有關的任何想法? – user700774

+0

對不起,我的印象是你使用了多個定時器或線程。這幾乎肯定會造成太多人在跑步的問題。很高興你的問題得到解決:) – mjdth

0

我想你會發現,即使你優化了這個,基於定時器的動畫這樣的表現也不會很好。

你可能想問一下你認爲你無法用CoreAnimation做的具體事情。如果你解決了這些問題,你最終會得到比試圖推出自己的更好的結果。

+0

感謝您的反饋。我不太確定那將如何工作。例如,假設我已經讓我的圖像沿着一條線移動,並且在給定的點上我想確定它的位置。或者沒有實際執行動畫,找出它應該在哪裏。或取消它。我如何使用簡單的UIView animateWithDuration方法來做到這一點? – user700774