ScrollView runs out of memory when it gets too big

2019-08-14 02:21发布

I've an app which provides to the user some sort of a line graph. I'm using an UIScrollView which is containing the view with graph. The view is using CoreGraphics to draw the graph in it's drawrect method. The problem arises when the graph gets too long. Scrolling through the graph seems to stutter and eventually the app would run out of memory and exit. Looking around at other apps I see the guys who created the WeightBot app were able to manage long ongoing graphs without any problems so apparently I'm doing it the wrong way.

I was wondering how this sort of long line graphs are created without bumping into memory issues?

EDIT: adding some code

Basically all I do is init the view which build's the graph in it's drawRect method and add the view as a subView to the scrollView.

This is how the view's drawRect is implemented:

- (void)drawRect:(CGRect)rect 
{
CGContextRef c = UIGraphicsGetCurrentContext();

CGContextSetFillColorWithColor(c, self.backgroundColor.CGColor);
CGContextFillRect(c, rect);

//... do some initialization 

 for (NSUInteger i = 0; i < xValuesCount; i++) 
    {
        NSUInteger x = (i * step) * stepX;

        NSUInteger index = i * step;

        CGPoint startPoint = CGPointMake(x + offsetX, offsetY);
        CGPoint endPoint = CGPointMake(x + offsetX, self.frame.size.height - offsetY);

        CGContextMoveToPoint(c, startPoint.x, startPoint.y);
        CGContextAddLineToPoint(c, endPoint.x, endPoint.y);
        CGContextClosePath(c);

        CGContextSetStrokeColorWithColor(c, self.gridXColor.CGColor);
        CGContextStrokePath(c);
    }
}

3条回答
迷人小祖宗
2楼-- · 2019-08-14 02:37

The rect argument of drawRect: indicates which section of your view you're being asked to draw. You should add some logic to work out which parts of your graph are in that rect and only draw those, instead of redrawing the whole thing on every call.

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-08-14 02:38

A large view (with a draw method) takes lots of memory, even if its superview is small. Your oversized subview will require a huge backbuffer.

Instead, simply subclass directly from the uiscrollingview. The scrollingview is only as big as its visual part. The offset is automatically taken care of when drawing. Your draw method will be called all the time, but that should be okay.

查看更多
冷血范
4楼-- · 2019-08-14 02:46

Figure out what portion of your data set is visible, and only draw what you need to.

查看更多
登录 后发表回答