2009-08-31 25 views
1

簡單繪畫:
指法iPhone屏幕將臨時圖形繪製到UIView。這些臨時圖形在觸摸結束後被刪除,然後存儲到底層的UIView中。提高手指畫的性能

的過程很簡單:
1)觸摸啓動&移至>>
2)油漆在頂部的UIView臨時圖形>>
3)觸摸結束>>
4)將臨時圖形傳遞到底層UIView >>
5)底層UIView將臨時圖形添加到存儲圖形>>
6)標的的UIView重新把一切存儲的圖形>>
7)刪除頂部的UIView臨時圖形。

以這種方式,我可以在底層UIView上積累圖形,同時保持頂層UIView上臨時圖形的響應式繪製。

(旁註:每個「繪圖」是簡單地定製的一個NSArray「點」的對象,其只是NSObject的容器CGPoints和底層的UIView具有一個單獨的NSArray,其中存儲CGPoints這些NSArrays。)

問題是:
當大量的圖形積累在底層的UIView上時,需要花費時間將它全部繪製在屏幕上。在底層存儲圖形繪製完成之前,頂層UIView上的任何新圖形都不會顯示。因此,當許多圖形出現在屏幕上時,會有明顯的滯後。

問:
誰能想到在這裏提高性能的好辦法,以便有圖紙之間沒有noticable滯後時,也有很多在屏幕上的圖形?

回答

2

一個NSArray的CGPoints?你的意思是NSArray的NSValues持有CGPoints?這是一個非常耗費時間的方法,可以持續不斷地訪問大量價值。您可以以更好的方式存儲這些信息。代表整個屏幕的二維C陣列是最明顯的。您可能還想查看位圖圖像表示,並直接繪製成CGImage,而不是維護一堆CGPoint。看看Quartz 2D Programming Guide

編輯:

你的對象(下圖)是NSValue相當於,只是有點更加專業化。當你有很多很多的對象時,會有很多開銷(當屏幕快滿時我會猜測大約100,000;如果你沒有刪除重複的內容,運行Instruments來分析它們會更多)。舊式的C數據結構可能會更快,因爲你可以避免所有的保留/釋放,分配等等。然而,還有其他的選擇。如果您像素對齊CGPoints,並且在Point對象上過載-isEqual,則重複點檢查會更快,NSMutableSet

確保像素對齊您的數據。藉助分數像素(並將它們全部存儲),可以顯着增加所涉及的對象數量和您正在執行的繪圖數量。即使您想要抗鋸齒,至少將像素四捨五入到.5(或.25或某物)。一個CGPoint由兩個雙打組成。你不需要那種精確度來繪製屏幕。

+0

不,我沒有使用NSValue來保存CGPoint。我分類了NSObject並給了它兩個成員:xCoord和yCoord,它們是CGPoints。實際上,在屏幕幾乎被圖形覆蓋之前,性能似乎並不是那麼糟糕。我不訪問存儲的圖形,直到用戶擡起他/她的手指(僅在中間的圖形中),此時我繪製存儲的所有內容......我保留點,以便我可以回溯並執行撤消操作需要。 C陣列會更快嗎? – RexOnRoids 2009-08-31 02:46:47

+0

根據評論編輯答案。 – 2009-08-31 03:02:01

1

爲什麼不把所有東西都繪製到一個CGBitmapContextRef緩衝區中,這樣繪圖操作就會累積起來,然後將其繪製到drawRect:的屏幕上?隨着操作總數的增加,您將能夠執行任意圖形操作而不會減慢速度。

如果需要撤消支持,則可以隨時爲每次更改保留一個副本,並在收到內存警告時使最舊的副本無效。 (或者對於更有愛好的解決方案,像現在一樣存儲操作,但保留每十個用戶操作的緩存副本等)

+0

感謝您的回答。如何在-drawRect:方法中一起繪製多個CGImageRef(每個表示筆劃)? – RexOnRoids 2009-09-08 05:13:57

+0

您應該使用一個CGBitmapContextRef作爲您的後備緩衝區。當你在上下文上繪製一條新路徑時,它會在舊內容之上繪製。在視圖的drawRect中:使用CGBitmapContextCreateImage獲取圖像,然後將其繪製到視圖上。爲了實現這個,只需要一個CGBitmapContextRef – rpetrich 2009-09-08 06:59:31