iPhone + UIView。在drawRect期间消耗大量内存。有什么策略可以减少这种情况? [英] iPhone + UIView. Enormous memory consumption during drawRect. Any strategies for reducing this?

查看:108
本文介绍了iPhone + UIView。在drawRect期间消耗大量内存。有什么策略可以减少这种情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的数据可视化应用程序在重绘期间会引发大量内存消耗高峰(setNeedsDisplay会触发drawRect)。我目前正在重绘容纳数据图的整个视图。该视图远大于设备显示。

My data visualization app incurs a large memory consumption spike during redraw (setNeedsDisplay which triggers drawRect). I am currently redrawing the entire view that houses the data plot. This view is much larger then the device display.

有没有办法告诉CoreGraphics分配足够的内存来绘制每个元素(每个元素都是一个小的矩形块,小于设备的显示屏)并在完成后释放内存,而不是我当前的幼稚方法?

Is there any way to tell CoreGraphics to allocate just enough memory to draw each element (each element is a small rectangular block much smaller then the device display) and release the memory when done, rather then my current naive approach?

预先感谢。

-Doug

UPDATE 12月8日8:28 am EST

UPDATE 8 Dec 8:28am EST

以下是与说明有关的代码话语。我正在运行具有ObjectAlloc,Memory Monitor和Leaks仪器的仪器。我唯一的内存泄漏是由于NSOperationQueue没有释放内存而引起的。这是次要的,无关紧要的。

Here is the relevant code with explanatory wordage. I am running Instruments with ObjectAlloc, Memory Monitor, and Leaks instruments running. The only memory leak I have is due has to do with the NSOperationQueue not releasing mems. This is minor an not relevant.

Architecturally该应用程序由一个tableView组成,其中包含人类基因组中要检查的有趣位置的列表。当选择一个表行我入队的将数据收集操作调用alignmentData返回数据。然后将此数据绘制为水平矩形平板。

Architecturally the app consists of a tableView with a list of interesting locations along the human genome to inspect. When a table row is selected I enqueue a data gathering operation that returns data called alignmentData. This data is then plotted as horizontal rectangular slabs.

最初,当tableView启动时,我的内存占用为5 MB。

Initially, when the tableView launches my memory footprint is 5 MB.

- (void)viewWillAppear:(BOOL)animated {

    // Initial dimensions for the alignment view are set here. These
    // dimensions were roughed out in IB.

    frame                       = self.alignmentView.frame;
    frame.origin.x              = 0.0;
    frame.origin.y              = 0.0;  
    frame.size.width            = self.scrollView.contentSize.width;    
    frame.size.height           = 2.0 * (self.containerView.frame.size.height);

}

注意:在viewWillAppear之后:称为内存占用还没有发芽。即使alignmentView的大小远远超出了显示的尺寸。

Note: After viewWillAppear: is called the memory footprint has not budged. Even though the alignmentView is be sized well beyond the dimensions of the display.

这是从数据收集操作中调用的方法。

This is the method called from the data gathering operation.

- (void)didFinishRetrievingAlignmentData:(NSDictionary *)results {

        // Data retrieved from the data server via the data gathering operation
    NSMutableData *alignmentData = [[results objectForKey:@"alignmentData"] retain];

    NSMutableArray *alignments = [[NSMutableArray alloc] init];
    while (offset < [alignmentData length]) {

        // ...
        // Ingest alignmentData in alignments array 
        // ...  

    } // while (offset < [alignmentData length])    
    [alignmentData release];

    // Take the array of alignment objects and position them in screen space 
        // so that they pack densely creating horizontal rows of alignment objects 
        // in the process.
    self.alignmentView.packedAlignmentRows = 
    [Alignment packAlignments:alignments basepairStart:self.startBasepairValue basepairEnd:self.endBasepairValue];  
    [alignments release];

    [self.alignmentView setNeedsDisplay];

}

在此代码行之后:

self.alignmentView.packedAlignmentRows = ...

内存占用量为13.8 MB

The memory footprint is 13.8 MB

此行代码之后:

[self.alignmentView setNeedsDisplay];

内存占用量飙升至21.5 MB,停留在那里几秒钟,然后返回到原来的状态13.8 MB的级别

The memory footprint spikes to 21.5 MB, stays there for a few seconds then returns to the pre-existing level of 13.8 MB

我正在寻找的解决方案实际上将允许我创建一个水平渲染缓冲区窗口,该窗口即为一行对齐对象的高度。我会在其中分配其内存渲染,然后将其丢弃。我会一遍又一遍地对对齐数据的每一行进行此操作。

The solution I am looking for would allow me to essentially, create a horizontal render buffer window that that is the height of a single row of alignment objects. I would allocate its memory render into it, then discard it. I would do this over and over again for each row of alignment data.

理论上,我可以使用这种方法来渲染无限量的数据,这当然是最有效的方法。优秀;-)。

In theory, I could render an infinite amount of data with this approach which of course would be most excellent ;-).

-道格

推荐答案

-对我的记忆力问题没有那么明显的答案。我给自己一个,因为我是在Apple开发人员论坛Rincewind上学到的,这是一个非常有帮助的Apple工程师BTW。

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.

事实证明,通过切大视图分成N个较小的块,然后依次渲染成每个块,我将产生一个内存峰值,大约是大视图大小的1 / N。

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.

因此,对于每个较小的视图:alloc / init,提供部分数据setNeedsDisplay。冲洗/重复全部N个小视图。

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

简单,是吗?

在学习之前,我曾错误地认为setNeedsDisplay:myRect是针对大视图执行的操作。显然不是。

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

感谢所有建议帮派。

干杯,
道格
@dugla

Cheers, Doug @dugla

这篇关于iPhone + UIView。在drawRect期间消耗大量内存。有什么策略可以减少这种情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆