iPhone + UIView. Enormous memory consumption during drawRect. Any strategies for reducing this?

百般思念 提交于 2019-12-06 07:08:27

Here is the - not so obvious answer to my memory problem. I'll give myself this one because I learned it on the Apple dev forum form Rincewind - a very helpful Apple engineer BTW.

It turns out that by slicing a large view into N smaller pieces and rendering into each in turn I will incur a memory spike that is roughly 1/N the size of the large view.

So, for each smaller view: alloc/init, feed a portion of my data, setNeedsDisplay. Rinse/repeat for all N small views.

Simple, eh?

Prior to learning this I had mistakenly thought that setNeedsDisplay:myRect did this for the large view. Apparently not.

Thanks for all the suggestions gang.

Cheers, Doug @dugla

"This view is much larger then the device display."

So you're scrolling through the data representation by moving the view around? You might want to consider making your view the same size as the display and using CGTranslate to adjust the drawing offset within your drawRect function. It sounds like you're drawing tons of stuff, and CoreGraphics can't tell what's visible and what is not.

You'll get much better drawing performance if you make the view smaller and insert checks to avoid drawing things that are outside the view's bounds.

This is very possible, you will need to specify which sections of the screen need to be drawn, you need to call setNeedsDisplayInRect as described here and pass in a CGRect which is the area you wish to be redrawn.

This is much, much faster than re-drawing the entire screen, I had issues with this in an iPhone drawing application I created a year and a half ago.

In addition to Ben's suggestion:

If you're scrolling around your data, consider adding a few smaller views to the scrollview. This way you don't need to redraw most of the time, but only when some area of your scrollview isn't covered any more. Basically, if one of your subviews scrolls completely out of sight you'd move it to the opposite side of the visible area and redraw it accordingly.

In my app I'm only scrolling horizontally, and am using two subviews. Let's say view1 is on the left and view2 on the right. When view2 scrolls out of sight, I move it to the left of view1 and redraw it accordingly. If the user scrolls further in the same direction view1 will scroll out of sight as well and I'll move it to the left of view2 and so on.

If you need to scroll horizontally and vertically you'd need 4 views.

I know you are probably aware of this, but have you looked at the Core Plot framework for your data visualization? We recently added touch-scrolling of graphs and we've tried to be conservative when it comes to memory within the framework. Without knowing more about your specific case, this might be something you could try.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!