核心图:内存问题核心动画无法分配这么多字节

时间:2012-04-09 09:19:19

标签: ios core-plot

我使用核心图来生成使用webservices的各种类型的图。但是在生成大约60个图之后,图形scren看起来是空白的,在设备日志中给出了一条消息“核心动画未能分配9997432字节” 我们只在设备上遇到此问题,因为应用程序在模拟器上正常运行。

以下是代码片段,我们将数据从另一个类传递给下面的类。 .h文件

//
//  LineGraph.h
//  Graphs
//
//  Created by Pawan on 12/12/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "CorePlot-CocoaTouch.h"


@interface LineGraph1 : UIViewController<CPTPlotDataSource,UIPopoverControllerDelegate,CPTScatterPlotDelegate,CPTPlotSpaceDelegate> {

    NSMutableArray *xAxisValuesArray;
    NSMutableArray *yAxisValuesArray;
    NSMutableArray *identifierArray;
    NSMutableArray *xAxisScaleArray;
    NSMutableArray *formattedDataLabelArray;

    NSString  *graphTitleLabel;
    NSString *lineType;
    NSString *xAxisTitleLabel;
    NSString *yAxisMin;
    NSString *yAxisMax;
    NSString *yAxisIntervalLength;
    NSString *yAxisTitle;
    NSString *yAxisTitleLocation;
    UILabel *valueLabel2;


    float xAxiscount;
    float intervalLength;

    @private

    CPTXYGraph *lineGraph;
    CPTMutableTextStyle *titleTextStyle;
    CPTLayerAnnotation   *symbolTextAnnotation;

    NSMutableArray *plotSymbolColoursArray;
    NSMutableArray *plotLineColoursArray;

    IBOutlet CPTGraphHostingView *lineGraphtView;
    IBOutlet UILabel *lineGraphLabel;
    IBOutlet UISlider *lineGraphValueSlider;
    IBOutlet UIButton *drillUpButton;
    IBOutlet UIButton *drillDownButton;
    IBOutlet UIButton *helpButton;
}
@property(nonatomic,retain) IBOutlet CPTGraphHostingView *lineGraphtView;
@property(nonatomic,retain) CPTXYGraph *lineGraph;
@property(nonatomic,retain) NSMutableArray *xAxisValuesArray;
@property(nonatomic,retain) NSMutableArray *yAxisValuesArray;
@property(nonatomic,retain) IBOutlet UILabel *lineGraphLabel;
@property(nonatomic,retain) NSString *graphTitleLabel;
@property(nonatomic,retain) NSString *lineType;
@property(nonatomic,retain) NSString *xAxisTitleLabel;
@property(nonatomic,retain) NSString *yAxisTitleLocation;
@property(nonatomic,retain) NSString *yAxisMin;
@property(nonatomic,retain) NSString *yAxisMax;
@property(nonatomic,retain) NSString *yAxisIntervalLength;
@property(nonatomic,retain) NSString *yAxisTitle;
@property(nonatomic,retain) NSMutableArray *identifierArray;
@property(nonatomic,retain) NSMutableArray *plotSymbolColoursArray;
@property(nonatomic,retain) NSMutableArray *plotLineColoursArray;
@property(nonatomic,retain) NSMutableArray *xAxisScaleArray;
@property(nonatomic,retain) NSMutableArray *formattedDataLabelArray;
@property(nonatomic,retain) CPTMutableTextStyle *titleTextStyle;

- (void)constructLineGraphForSingleLineGraph:(NSString *)type;
-(IBAction)helpButtonPressed:(id)sender;
-(void)plotDataActionSlider:(id)sender;
-(void)setplotDataActionSlider;

@end



.m file




// LineGraph.m
//  Graphs
//
//  Created by Pawan on 12/12/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "LineGraph1.h"
#import "CommonMethodForGraphs.h"
#import "GraphDescription.h"

@implementation LineGraph1

@synthesize lineGraph;
@synthesize xAxisValuesArray;
@synthesize yAxisValuesArray;
@synthesize graphTitleLabel;
@synthesize lineGraphLabel;
@synthesize lineType;
@synthesize xAxisTitleLabel;
@synthesize yAxisMin;
@synthesize yAxisMax;
@synthesize yAxisIntervalLength;
@synthesize yAxisTitle;
@synthesize yAxisTitleLocation;
@synthesize identifierArray;
@synthesize plotLineColoursArray;
@synthesize plotSymbolColoursArray;
@synthesize xAxisScaleArray;
@synthesize formattedDataLabelArray;
@synthesize titleTextStyle;
@synthesize lineGraphtView;
//Implement viewDidLoad to do additional setup after loading the view, typically from a nib.


- (void)viewDidLoad {
    [super viewDidLoad];
    [self setplotDataActionSlider]; 
    self.lineGraphLabel.text=self.graphTitleLabel;
    NSMutableArray *identifierLocalArray=[[NSMutableArray alloc]init];

    [identifierLocalArray insertObject:@"Port In" atIndex:0];
    self.identifierArray=identifierLocalArray;
    [identifierLocalArray release];

    NSMutableArray *plotSymbolColoursLocalArray =[NSMutableArray arrayWithObjects:[CPTColor redColor],[CPTColor greenColor],nil];
    NSMutableArray *plotLineColoursLocalArray =[NSMutableArray arrayWithObjects:[CPTColor greenColor],[CPTColor redColor],nil];
    self.plotSymbolColoursArray=plotSymbolColoursLocalArray;    
    self.plotLineColoursArray=plotLineColoursLocalArray;

    if ([self.xAxisValuesArray count]<=10) 
    {
        xAxiscount = 10.0f;
    }
    else    
    {
        xAxiscount = 31.0f;
    }

    [self constructLineGraphForSingleLineGraph:self.lineType];

}
#pragma mark -
#pragma mark constructLineGraphForSingleLineGraph



- (void)constructLineGraphForSingleLineGraph:(NSString *)type
{

    // Create lineGraph from theme

    CPTXYGraph *lineGraphLocalObject = [[CPTXYGraph alloc] initWithFrame:CGRectZero];
    self.lineGraph = lineGraphLocalObject;
    [lineGraphLocalObject release];
    CPTTheme *theme = [CPTTheme themeNamed:kCPTPlainWhiteTheme];
    self.lineGraph = (CPTXYGraph *)[theme newGraph];

/*  
    UIImage *image = [UIImage imageNamed:@"BackgroundforGraph.png"];
    CGImageRef mycgimage = [image CGImage];
    CPTImage *image1 = [CPTImage imageWithCGImage:mycgimage];
    self.lineGraph.fill=[CPTFill fillWithImage:image1];
    self.lineGraph.borderLineStyle = nil;
    image = [UIImage imageNamed:@"PlotAreaImageNew.png"];
    mycgimage = [image CGImage];
    image1 = [CPTImage imageWithCGImage:mycgimage];

    self.lineGraph.plotAreaFrame.fill = [CPTFill fillWithImage:image1];
 */
    lineGraphtView.hostedGraph = self.lineGraph;
    lineGraphtView.allowPinchScaling = NO;
    self.lineGraph.plotAreaFrame.masksToBorder = NO;
    //padding for plot area
    self.lineGraph.paddingLeft = 110.0;
    self.lineGraph.paddingTop = 20.0;
    self.lineGraph.paddingRight = 10.0;
    self.lineGraph.paddingBottom = 100.0;

    // Add plot space for line graph
    CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)self.lineGraph.defaultPlotSpace;
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromString(self.yAxisMin) length:CPTDecimalFromString(self.yAxisMax)];
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0f) length:CPTDecimalFromFloat(xAxiscount)];

    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)self.lineGraph.axisSet;

    CPTXYAxis *x = axisSet.xAxis;
    x.majorIntervalLength = CPTDecimalFromString(@"1");
    x.orthogonalCoordinateDecimal = CPTDecimalFromString(self.yAxisMin);
    x.title =self.xAxisTitleLabel;
    x.titleLocation = CPTDecimalFromFloat(5.0f);
    x.titleOffset = 65.0f;
    x.labelOffset=0.0f;

    //text style initialized for both x and y axis....
    CPTMutableTextStyle *titleTextStyleLocalObject = [[CPTMutableTextStyle alloc] init];
    self.titleTextStyle = titleTextStyleLocalObject;
    [titleTextStyleLocalObject release];
    self.titleTextStyle.fontSize = 15;
    x.titleTextStyle =  self.titleTextStyle;
    self.titleTextStyle.fontSize = 12;
    x.labelTextStyle = self.titleTextStyle;

    // Define some custom labels for the data elements
    x.labelRotation = M_PI/4;
    x.labelingPolicy = CPTAxisLabelingPolicyNone;
    int labelLocation = 0;
    NSMutableArray *customLabelsForXaxis = [NSMutableArray arrayWithCapacity:[self.xAxisScaleArray count]];

    for (NSNumber *tickLocation in self.xAxisScaleArray) 
    {
        CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText: [self.xAxisScaleArray objectAtIndex:labelLocation++] textStyle:x.labelTextStyle];
        newLabel.tickLocation = [[NSNumber numberWithInt:labelLocation] decimalValue] ;//[tickLocation decimalValue];
        newLabel.offset =0.0;
        newLabel.rotation = M_PI/4;

        [customLabelsForXaxis addObject:newLabel];
        [newLabel release];
    }

    x.axisLabels =  [NSSet setWithArray:customLabelsForXaxis];  

    NSNumberFormatter *yAxisFormat = [[NSNumberFormatter alloc] init];
    [yAxisFormat setNumberStyle:NSNumberFormatterNoStyle];
    CPTXYAxis *y = axisSet.yAxis;
    y.axisLineStyle = nil;
    y.majorIntervalLength = CPTDecimalFromString(self.yAxisIntervalLength);
    y.orthogonalCoordinateDecimal = CPTDecimalFromString(@"0"); 
    y.titleOffset = 50.0f;
    y.titleLocation = CPTDecimalFromString(self.yAxisTitleLocation);
    y.labelOffset = 0.0f;
    y.labelFormatter=yAxisFormat;
    [yAxisFormat release];
    y.title = self.yAxisTitle;
    y.labelTextStyle =  self.titleTextStyle;

    CPTScatterPlot *dataSourceLinePlot = [[[CPTScatterPlot alloc] init] autorelease];
    dataSourceLinePlot.identifier = [self.identifierArray objectAtIndex:0];

    CPTMutableLineStyle *lineStyle = [[dataSourceLinePlot.dataLineStyle mutableCopy] autorelease];
    lineStyle.lineWidth = 2.0f;
    lineStyle.lineColor = [ self.plotLineColoursArray objectAtIndex:0];//[CPTColor clearColor];for scatterplot
    dataSourceLinePlot.dataLineStyle = lineStyle;
    dataSourceLinePlot.labelOffset=8.0f;
    dataSourceLinePlot.dataSource = self;
    dataSourceLinePlot.delegate = self;

        // Add plot symbols

    CPTPlotSymbol *plotSymbol = [CPTPlotSymbol ellipsePlotSymbol];
    plotSymbol.fill = [CPTFill fillWithColor:[  self.plotSymbolColoursArray objectAtIndex:0]];
    plotSymbol.size = CGSizeMake(10.0, 10.0);
    dataSourceLinePlot.plotSymbol = plotSymbol;



    // Put an area gradient under the plot above
    CPTColor *areaColor = [CPTColor colorWithComponentRed:0.3 green:0.8 blue:0.3 alpha:0.6];
    CPTGradient *areaGradient = [CPTGradient gradientWithBeginningColor:areaColor endingColor:[CPTColor clearColor]];
    areaGradient.angle = -90.0;
    CPTFill* areaGradientFill = [CPTFill fillWithGradient:areaGradient];
    dataSourceLinePlot.areaFill = areaGradientFill;
    dataSourceLinePlot.areaBaseValue = CPTDecimalFromString(@"0.0");



    [self.lineGraph addPlot:dataSourceLinePlot];
    y.labelingPolicy = CPTAxisLabelingPolicyNone;
    intervalLength = [CommonMethodForGraphs formattedIntervalLengthForgraph:self.yAxisIntervalLength];


    double j=[self.yAxisMin intValue];
    NSMutableArray *customTickLocationsForYaxis = [[NSMutableArray alloc]init];
    NSMutableArray *yAxisLabels =[[NSMutableArray alloc]init];

    for (int h=0; h<=10; h++) 
    {
        [customTickLocationsForYaxis insertObject:[NSDecimalNumber numberWithLongLong:j] atIndex:h];
        [yAxisLabels insertObject:[[NSNumber numberWithLongLong:j/intervalLength]stringValue] atIndex:h];
        j=j+[self.yAxisIntervalLength longLongValue];
    }
    labelLocation = 0;
    NSMutableArray *customLabelsForYaxis = [[NSMutableArray alloc] initWithCapacity:[yAxisLabels count]];

    for (NSNumber *tickLocationForYaxis in customTickLocationsForYaxis)
    {
        CPTAxisLabel *newLabel = [[CPTAxisLabel alloc] initWithText: [yAxisLabels objectAtIndex:labelLocation++] textStyle:x.labelTextStyle];
        newLabel.tickLocation = [tickLocationForYaxis decimalValue];
        newLabel.offset = y.labelOffset + y.majorTickLength;
        [customLabelsForYaxis addObject:newLabel];
        [newLabel release];
    }

    y.axisLabels =  [NSSet setWithArray:customLabelsForYaxis];

    [customLabelsForYaxis release];
    [customTickLocationsForYaxis release];
    [yAxisLabels release];

}


#pragma mark -
#pragma mark delegates for Line graph 

-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot 
{
    int recordCount = 0;

    for (int i=0; i<[self.identifierArray count]; i++) 
    {
        if ( [plot.identifier isEqual:[self.identifierArray objectAtIndex:i] ]) 
        {
            recordCount= [self.yAxisValuesArray count];
        }

    }
    return recordCount; 
}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index 
{
    NSNumber *num = nil;

    if( [plot.identifier isEqual:[self.identifierArray objectAtIndex:0] ]) 
    {
        switch (fieldEnum) 
        {
            case CPTScatterPlotFieldX:
                num = [self.xAxisValuesArray objectAtIndex:index];
                break;

            case CPTScatterPlotFieldY:
                num = [self.yAxisValuesArray objectAtIndex:index];
                break;
        }

    }

    return num;
}


-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index
{

    static CPTMutableTextStyle *whiteText = nil;

    if ( !whiteText) 
    {
        whiteText = [[CPTMutableTextStyle alloc] init];
        whiteText.color = [CPTColor blackColor];
        whiteText.fontSize=12.0f;
    }

    CPTTextLayer *newLayer = nil;
    if (index%2==0) 
    {
        plot.labelOffset=-0.5;

    }
    else 
    {
        plot.labelOffset=0.5;
    }


    if ( [plot.identifier isEqual:[self.identifierArray objectAtIndex:0]])
    {
        newLayer = [[[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:@"%.1f%",[[self.formattedDataLabelArray objectAtIndex:index]floatValue]] style:whiteText] autorelease];
        [whiteText release];
    }

    return newLayer;

}

-(void)scatterPlot:(CPTScatterPlot *)plot plotSymbolWasSelectedAtRecordIndex:(NSUInteger)index
{

    if ( symbolTextAnnotation ) {
        [self.lineGraph.plotAreaFrame.plotArea removeAnnotation:symbolTextAnnotation];
        symbolTextAnnotation = nil;
    }

    // Setup a style for the annotation
    CPTMutableTextStyle *hitAnnotationTextStyle = [CPTMutableTextStyle textStyle];
    hitAnnotationTextStyle.color = [CPTColor redColor];
    hitAnnotationTextStyle.fontSize = 16.0f;
    hitAnnotationTextStyle.fontName = @"Helvetica-Bold";

    // Determine point of symbol in plot coordinates
    NSNumber *x = [self.xAxisValuesArray objectAtIndex:index];

    NSString *y = [self.yAxisValuesArray objectAtIndex:index];

    NSArray *anchorPoint = [NSArray arrayWithObjects:x, y, nil];



    // Now add the annotation to the plot area
    CPTTextLayer *textLayer = [[[CPTTextLayer alloc] initWithText:y style:hitAnnotationTextStyle] autorelease];

    symbolTextAnnotation = [[CPTPlotSpaceAnnotation alloc] initWithPlotSpace:self.lineGraph.defaultPlotSpace anchorPlotPoint:anchorPoint];

    symbolTextAnnotation.contentLayer = textLayer;
    symbolTextAnnotation.displacement = CGPointMake(0.0f, 20.0f);
    [self.lineGraph.plotAreaFrame.plotArea addAnnotation:symbolTextAnnotation]; 
    [textLayer release];
    [symbolTextAnnotation release];
}

#pragma mark -
#pragma mark method for slider action


-(void)plotDataActionSlider:(id)sender
{


    if (lineGraphValueSlider.value<=[self.yAxisValuesArray count]+1) 
    {
            //code to remove added imageView
            [[self.view viewWithTag:50] removeFromSuperview];
            //code to remove added label
            [[self.view viewWithTag:100] removeFromSuperview];
        for (int d=0; d<[self.yAxisValuesArray count]; d++) 
        {
            if ((int)lineGraphValueSlider.value==[[self.xAxisValuesArray objectAtIndex:d]intValue]) 
            {



                int x=300;
                valueLabel2=[[UILabel alloc]init];
                valueLabel2.frame=CGRectMake(x, 620, 300, 40);
                valueLabel2.tag=100;
                NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; 
                [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
                NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
                [formatter setLocale:locale];
                valueLabel2.text= [[[self.xAxisScaleArray objectAtIndex:d] stringByAppendingString:@" : "] stringByAppendingString:[formatter stringFromNumber:[NSNumber numberWithLongLong:[[self.yAxisValuesArray objectAtIndex:d]longLongValue]]]];
                [self.view addSubview:valueLabel2];
                [valueLabel2 release];
                [formatter release];

            }
        }
    }
    else 
    {
        [[self.view viewWithTag:50] removeFromSuperview];
        [[self.view viewWithTag:100] removeFromSuperview];

    }



}

-(void)setplotDataActionSlider
{
    UIImage *minImage = [UIImage imageNamed:@"SliderRoll.png"];
    UIImage *tumbImage= [UIImage imageNamed:@"SliderArrow.png"];   
    minImage=[minImage stretchableImageWithLeftCapWidth:0 topCapHeight:0];
        // Setup the  slider
    [lineGraphValueSlider setMinimumTrackImage:minImage forState:UIControlStateNormal];
    [lineGraphValueSlider setThumbImage:tumbImage forState:UIControlStateNormal];
    lineGraphValueSlider.minimumValue = 0.0;

    if ([self.xAxisValuesArray count]<=10)
    {
        lineGraphValueSlider.maximumValue = 10.0;
    }
    else 
    {
        lineGraphValueSlider.maximumValue = 31.0;
    }


    lineGraphValueSlider.continuous = YES;
    [lineGraphValueSlider addTarget:self action:@selector(plotDataActionSlider :) forControlEvents:UIControlEventValueChanged];

    minImage = nil;
    tumbImage = nil;


}   

#pragma mark -
#pragma mark method for help drill up and drill down

-(IBAction)helpButtonPressed:(id)sender{
    [CommonMethodForGraphs helpButtonActionForAllGraphs:self.view];


}
#pragma mark -

//Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations.
    return ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||(interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}


- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc. that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];

    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.lineGraphLabel = nil;
    self.lineGraphtView = nil;
}


- (void)dealloc {

    [lineGraph release];
    [xAxisValuesArray release];
    [yAxisValuesArray release];
    [xAxisTitleLabel release];  
    [graphTitleLabel release];
    [lineGraphLabel release];
    [lineType release];
    [yAxisMin release];
    [yAxisMax release];
    [yAxisIntervalLength release];
    [yAxisTitle release];
    [yAxisTitleLocation release];
    [identifierArray release];
    [plotLineColoursArray release];
    [plotSymbolColoursArray release];
    [xAxisScaleArray release];
    [formattedDataLabelArray release];
    [lineGraphtView release];
    [super dealloc];

}



@end

2 个答案:

答案 0 :(得分:0)

不确定这是否会产生很大的不同,但这两种方法似乎使用不同的逻辑

-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot 
{
int recordCount = 0;

for (int i=0; i<[self.identifierArray count]; i++) 
{
    if ( [plot.identifier isEqual:[self.identifierArray objectAtIndex:i] ]) 
    {
        recordCount= [self.yAxisValuesArray count];
    }
}
return recordCount; 

}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index 
{
NSNumber *num = nil;

if( [plot.identifier isEqual:[self.identifierArray objectAtIndex:0] ]) 
{
    switch (fieldEnum) 
    {
        case CPTScatterPlotFieldX:
            num = [self.xAxisValuesArray objectAtIndex:index];
            break;
        case CPTScatterPlotFieldY:
            num = [self.yAxisValuesArray objectAtIndex:index];
            break;
    }
}

return num;
}

我建议使用

中的相同逻辑
-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index

在另一种方法中

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

如果你的图表可以确认只有一个图吗?

答案 1 :(得分:0)

内存中的所有60个图表是否同时存在?如果是这样,您可能会耗尽Core Animation的内存或其他GPU资源。请务必释放您不再使用的图表和/或图表以释放资源。