2012-07-22 54 views
3

我正在使用核心绘图绘制图形。到目前为止,它似乎是一个很好的框架,但是当我启用用户交互并执行滚动时,我遇到了一些性能问题。CorePlot ScatterPlot滚动性能iPhone4

起初我以为这是由于被绘制点的数量所以我写了一个简单的测试应用程序,只有很少的几点。尽管情节尽可能简单,但滚动仍然很不平稳。在这个情节下,我在iPhone 4上获得20-25 fps的速度。

我做错了什么,或者这和核心情节一样快吗?

我的样本代码如下:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    graph = [(CPTXYGraph *)[CPTXYGraph alloc] initWithFrame:CGRectZero]; 

    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace; 
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length: CPTDecimalFromDouble(5)]; 
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0) length:CPTDecimalFromDouble(5)]; 
    plotSpace.allowsUserInteraction = YES; 
    plotSpace.globalYRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(-10) length:CPTDecimalFromDouble(100)]; 
    plotSpace.globalXRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromInt(-10) length:CPTDecimalFromDouble(20)]; 

    // Axes 
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet; 
    CPTXYAxis *x   = axisSet.xAxis; 
    x.majorIntervalLength   = CPTDecimalFromInt(1); 
    x.orthogonalCoordinateDecimal = CPTDecimalFromInt(0); 
    x.axisConstraints = [CPTConstraints constraintWithLowerOffset:30]; 

    CPTXYAxis *y = axisSet.yAxis; 
    y.majorIntervalLength   = CPTDecimalFromInt(1); 
    y.minorTicksPerInterval  = 0; 
    y.orthogonalCoordinateDecimal = CPTDecimalFromDouble(0); 
    y.axisConstraints = [CPTConstraints constraintWithLowerOffset:30]; 

    // Create a plot that uses the data source method 
    CPTScatterPlot *dataSourceLinePlot = [[CPTScatterPlot alloc] init]; 
    dataSourceLinePlot.identifier = @"1"; 

    CPTMutableLineStyle *lineStyle = [dataSourceLinePlot.dataLineStyle mutableCopy]; 
    lineStyle.lineWidth    = 3.f; 
    lineStyle.lineColor    = [CPTColor redColor]; 
    dataSourceLinePlot.dataLineStyle = lineStyle; 
    dataSourceLinePlot.dataSource = self; 
    dataSourceLinePlot.delegate = self; 
    [graph addPlot:dataSourceLinePlot]; 

    hostView.hostedGraph = graph; 
} 

-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot 
{ 
    return 20; 
} 

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index 
{ 
    return [NSNumber numberWithInt:index]; 
} 

回答

1

它的最好的,如果你在后台执行策划。

您可能正在尝试在主队列上绘制/处理这些图形,这很糟糕。正在发生的事情就是你所有的渲染,处理和你的用户触摸事件都被备份在主队列中,如下图所示。所以你得到的是绘图,处理和触摸事件正按照它们被接收的顺序(FIFO)发生。如果您将处理置于背景上,则触摸事件将在不等待的情况下处理。 (请观看下面引用的视频)

BAD (what you are probably doing) 
MainQueue: Process/Plot -> TouchEvent(scroll) -> Render -> Plot/Process -> Plot/Process -> TouchEvent(scroll) -> Update UI -> TouchEvent 

GOOD 
MainQueue: TouchEvent(scroll) -> TouchEvent(scroll) -> Update UI -> TouchEvent 
ProcessingQueue: Process/Plot -> Plot/Process -> Plot/Process 

它最好让MainQueue只处理渲染(UI更新)和触摸事件,把一切都在后台队列别人。

NSOperationQueue *q = [NSOperationQueue alloc] init]; 
[q setName:@"Plotting Queue"]; 
[q addOperationWithBlock:^{ plotGraph(); }]; 
[q addOperationWithBlock:^{ 
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 
     updateTheUI(); 
    }]; 
}]; 

plotGraph方法将上述所有的绘图代码。 updateTheUI方法将您的hostView.hostedGraph =图;加上任何代码以使UI重新呈现自己。

退房WWDC 2012的视频名为“构建并发用户界面iOS上的”

+0

当第一次加载图时,图委托最初被调用。它不会在每次后续重新加载或用户交互时调用。当滚动发生时,我相信CorePlot框架所做的唯一事情就是渲染。我并没有真正做任何背景任务,因为它是所有渲染相关的,所以我不认为你的建议适用于此,但如果我错了,请纠正我。 – Imran 2012-07-23 16:40:48

+0

您可能还需要将图形移至背景。什么样的viewController持有这些阴谋? ScrollView,TableView或? – jdog 2012-07-23 18:15:14

+0

另外你最好打赌是使用时间分析器查看什么是尖峰。 – jdog 2012-07-23 18:17:00

0

我有巨大的性能问题,我的散点图,直到我设置轴标签政策。将标签策略设置为“自动”或“无”可消除5秒的滞后时间。

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

不幸的是我需要轴标签。去除它们会产生轻微的性能改善,但不会太大。 – Imran 2012-08-30 14:27:38