菜鸟教程小白 发表于 2022-12-12 13:46:08

ios - 加载包含 Core Plot 图的 View Controller 时延迟过大


                                            <p><p>我刚开始使用 Core Plot,为了测试,在一个简单的自定义 ViewController 中嵌入了一个 <code>CPTGraphHostingView</code>,绘制来自 Core Data fetchRequest 的值(这是一个绘制每天膳食卡路里摄入量的应用程序)。</p>

<p>代码大部分是从教程 <a href="http://www.mobdevel.com/?p=96" rel="noreferrer noopener nofollow">here</a> 中粘贴的.</p>

<p>问题是当将 ViewController 插入 View 时 UI 卡住了大约两秒钟(它嵌入在导航 Controller 中)。这是在设备 (iPhone 4S) 上运行时。</p>

<p>Instruments 中的分析显示主线程被 <code></code> 和 <code></code> 阻塞。</p>

<p>延迟不是由于数据集过大:它目前正好包含两个点。该图<em>非常</em>简单,如下所示:</p>

<p> <img src="/image/MHOou.png" alt="enter image description here"/> </p>

<p> ViewController 的完整实现:​​</p>

<p>界面:</p>

<pre><code>//
//ICCaloriesGraphController.h
//iCalories
//
//Created by David Fearon on 22/08/2013.
//Copyright (c) 2013 David Fearon. All rights reserved.
//

#import &lt;UIKit/UIKit.h&gt;
#import &#34;CorePlot-CocoaTouch.h&#34;
#import &#34;ICDatabaseBrain.h&#34;
#import &#34;Day.h&#34;
#import &#34;CalorieEntry.h&#34;

@interface ICCaloriesGraphController : UIViewController&lt;CPTPlotDataSource, NSFetchedResultsControllerDelegate&gt;
@property (weak, nonatomic) IBOutlet CPTGraphHostingView *graphHostingView;
@property (nonatomic, retain)ICDatabaseBrain* sharedDatabaseBrain;
@property (nonatomic, retain)NSFetchedResultsController* resultsController;

@end
</code></pre>

<p>实现:</p>

<pre><code>//
//ICCaloriesGraphController.m
//iCalories
//
//Created by David Fearon on 22/08/2013.
//Copyright (c) 2013 David Fearon. All rights reserved.
//

#import &#34;ICCaloriesGraphController.h&#34;

@interface ICCaloriesGraphController ()

@property int numberOfRecordsForPlot;
@property float maxDailyCaloriesInDataset;
@property NSArray* days;

@end

@implementation ICCaloriesGraphController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = ;
    if (self) {
      // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    ;

    self.sharedDatabaseBrain = ;
    self.resultsController = self.sharedDatabaseBrain.fetchDaysResultsController;

    self.days = ;
    self.numberOfRecordsForPlot = ;

    ;

    // Create a CPTGraph object and add to hostView
    CPTGraph* graph = [ initWithFrame:self.graphHostingView.bounds];
    self.graphHostingView.hostedGraph = graph;

    // Get the (default) plotspace from the graph so we can set its x/y ranges
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) self.graphHostingView.hostedGraph.defaultPlotSpace;

    // Note that these CPTPlotRange are defined by START and LENGTH (not START and END) !!
    ];
    ];

    // Create the plot (we do not define actual x/y values yet, these will be supplied by the datasource...)
    CPTScatterPlot* plot = [ initWithFrame:CGRectZero];

    // Let&#39;s keep it simple and let this class act as datasource (therefore we implement &lt;CPTPlotDataSource&gt;)
    plot.dataSource = self;

    // Finally, add the created plot to the default plot space of the CPTGraph object we created before
    ;

}

-(void)viewWillAppear:(BOOL)animated{

    ;

}

- (void)didReceiveMemoryWarning
{
    ;
    // Dispose of any resources that can be recreated.
}


-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plotnumberOfRecords {
    return self.numberOfRecordsForPlot;
}


-(void)updateMaxDailyCaloriesInDataset{

    if (self.numberOfRecordsForPlot == 0){
      self.maxDailyCaloriesInDataset = 0;
      return;
    }

    int max = 0;

    for (Day* day in self.days) {

      //count the calories in the day:
      int calorieSum = 0;
      for (CalorieEntry* calorieEntry in ) {
            calorieSum += calorieEntry.calories.intValue;
      }

      if(calorieSum &gt; max) max = calorieSum;

    }

    self.maxDailyCaloriesInDataset = max;

}


-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{

    if (self.numberOfRecordsForPlot == 0){
      return 0;
    }

    if(fieldEnum == CPTScatterPlotFieldY){

      Day* day = ;

      //count the calories in the day:
      int calorieSum = 0;
      for (CalorieEntry* calorieEntry in ) {
            calorieSum += calorieEntry.calories.intValue;
      }

      return ;
      //TODO: Set range for y axis

    }

    if(fieldEnum == CPTScatterPlotFieldX){
      return ;
    }else{
      NSLog(@&#34;fieldEnum was neither CPTScatterPlotFieldY or CPTScatterPlotFieldX in numberForPlot:&#34;);
      return 0;
    }

}

@end
</code></pre>

<p>延迟绝对与 Core Data 代码无关;一切正常。谷歌搜索只会显示大型数据集的问题,而不是只有两点的问题。显然,我对核心情节代码做了一些根本性的错误,但真的看不出是什么。</p>

<p>请问有人能发现问题吗?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p><code>maxDailyCaloriesInDataset</code> 大吗?默认轴标签策略将刻度标记和标签沿轴分开一个单位。如果 <code>yRange</code> 很大,这会创建很多重叠的标签,这可能会非常慢。根据您的应用程序的要求,增加 <code>majorIntervalLength</code> 使其不会制作这么多标签,或者更改标签策略。 <code>CPTAxisLabelingPolicyAutomatic</code> 和 <code>CPTAxisLabelingPolicyEqualDivisions</code> 会是不错的选择。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 加载包含 Core Plot 图的 ViewController 时延迟过大,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/18404887/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/18404887/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 加载包含 Core Plot 图的 View Controller 时延迟过大