CorePlot多个散点图内存消耗巨大

3
我在使用CorePlot时遇到了一些问题。我试图将多个散点图绘制到一个图表中。虽然预期结果正确,但是当我开始滚动或缩放图表时,整个应用程序的内存使用量增加到900MB并崩溃了。我认为我需要释放一些对象,但我不知道怎么做。基本上,我使用不同的绘图标识符来绘制每条线,并将相应的数据放入数据源中。

这是我的代码:(在这个示例代码中,我只是为了测试目的而使用静态值减少了轴范围。)

- (void)setupGraph {
// Create graph from theme
self.graph = [[CPTXYGraph alloc] initWithFrame:self.scatterPlotView.bounds];
self.graph.plotAreaFrame.masksToBorder = NO;
self.scatterPlotView.hostedGraph = self.graph;

CPTTheme *theme = [CPTTheme themeNamed:kCPTPlainBlackTheme];
[self.graph applyTheme:theme];

self.graph.paddingLeft   = 0.0;
self.graph.paddingTop    = 0.0;
self.graph.paddingRight  = 0.0;
self.graph.paddingBottom = 0.0;


// Setup plot space
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.graph.defaultPlotSpace;

plotSpace.allowsUserInteraction = YES;

plotSpace.delegate = self;

plotSpace.globalXRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(30)];
plotSpace.globalYRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(15)];

plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(10)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(15)];

CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.graph.axisSet;
CPTXYAxis *x = axisSet.xAxis;
CPTXYAxis *y = axisSet.yAxis;
x.labelingPolicy = CPTAxisLabelingPolicyNone;
y.labelingPolicy = CPTAxisLabelingPolicyNone;
}

这个方法会加载我的数据并绘制散点图

- (void)loadSignals {


//Data loading logic goes here nothing special just one array for each plot

for (Signal *sig in [signals allValues]) {
    [self constructScatterPlot:sig.name];
}
}];

这是绘图发生的地方:
- (void)constructScatterPlot:(NSString *)identifier {    
    CPTScatterPlot *dataSourceLinePlot = [[CPTScatterPlot alloc] init];

   CPTMutableLineStyle *lineStyle = [dataSourceLinePlot.dataLineStyle mutableCopy];

    CPTScatterPlot *boundLinePlot = [[CPTScatterPlot alloc] init];
    boundLinePlot.identifier = identifier;

    lineStyle            = [boundLinePlot.dataLineStyle mutableCopy];
    lineStyle.miterLimit = 1.0;
    lineStyle.lineWidth  = 1.0;
    lineStyle.lineColor  = [CPTColor redColor];
    boundLinePlot.dataLineStyle = lineStyle;

    boundLinePlot.dataSource     = self;
    boundLinePlot.cachePrecision = CPTPlotCachePrecisionDouble;
    boundLinePlot.interpolation  = CPTScatterPlotInterpolationStepped;
    [self.graph addPlot:boundLinePlot];
}

这就是数据源获取其值的地方:

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
NSString *plotIdent = (NSString *) plot.identifier;

     if (![plotIdent isEqualToString:self.currentIdent]) {
        self.countPlot++;
        self.currentIdent = plotIdent;
    }

Signal *newSig = [self.signals objectForKey:plotIdent];
    Value * newValue = [newSig valueAtTime:index];
NSNumber *number = [NSNumber numberWithInteger:[newValue.value integerValue]];

    if ( fieldEnum == CPTScatterPlotFieldY ) {

        return number;
    }
    if ( fieldEnum == CPTScatterPlotFieldX ) {
        return [NSNumber numberWithInteger:index];
    }
    return nil;
}

首先,我想知道这是否是在一个图形中绘制多个图表的正确方式(在我的情况下最多有40个)?如果是这样,我应该如何优化我的绘图性能?

输出应该像这样: 预期(可滚动)输出


你使用countPlot做什么?每当Core Plot需要一个绘图点的坐标对时,numberForPlot就会被调用,因此随着移动或缩放,countPlot将变得更大。 - Dirk
只有在绘制新的图形(标识符)时,我的 countPlot 变量才会增加。该变量用于确定各个线条的 y 偏移量。 - dibi
2个回答

3

这实际上对我帮助很大。有了这个设置,加上超过40个实时散点图,当显示图形视图时,我的应用程序的内存使用从400 Mb以上平均降至35Mb。 - alcamla
我需要这个答案...谢谢! - Jim

2
每个图表都是一个覆盖整个图表区域的CALayer,因此如果有40个图表,您可能会使用掉大部分可用的视频内存。如果它们都使用相同的线条样式,您可以将所有线条绘制在同一图表上,并以此节省一些内存。在线段之间插入额外的数据点,并从数据源返回nil@(NAN)来断开线条。

我没有完全理解Eric的信息。Daniel,你有任何更新吗? 如果我理解得足够好,我的图表可能会相互交叉,因此额外的数据点不是解决方案。 - CppChase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接