Note that there are some explanatory texts on larger screens.

plurals
  1. POReduce Core-Graphics memory consumption on iphone
    text
    copied!<p>I am writing a program which redraws a graph every so often. Unfortunately it seems that for some reason core graphics does not seem to release the previous graphic so I run into memory problems fast. How can I force it to release memory at the end of each draw?</p> <p>Not that this is not a memory leak as the memory does get released when I leave close that view. I have tried moving the NSTimer to several places in the code to no avail.</p> <p>Here is the code below with the files going from most important to (potentially) irrelevant.</p> <p>First is the core file+header which draws the graphic (in this case a sine wave) every so often.</p> <p>GraphicsView.h</p> <pre><code>#import &lt;UIKit/UIKit.h&gt; #import "Model.h" @interface GraphicsView : UIView { Model * model; } @end </code></pre> <p>GraphicsView.m</p> <pre><code>#import "GraphicsView.h" @implementation GraphicsView - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { model=[Model sharedModel]; [NSTimer scheduledTimerWithTimeInterval:.010 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES]; } return self; } - (void)drawRect:(CGRect)rect { int now=[model n]; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextClearRect(context, CGRectMake(0, 0, rect.size.width, rect.size.height)); CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); CGContextMoveToPoint(context, 0.0, 0.0); double xc_old=0; double yc_old=100; for (int i=0;i&lt;now;i++) { double xc=(double)i/(double)now*200; double yc=100-100*sin((double)i/6); CGContextMoveToPoint(context, xc_old, yc_old); CGContextAddLineToPoint(context, xc, yc); CGContextStrokePath(context); xc_old=xc; yc_old=yc; } } - (void)dealloc { [super dealloc]; } @end </code></pre> <p>The view controller header:</p> <pre><code>#import &lt;UIKit/UIKit.h&gt; #import "GraphicsView.h" @interface SbarLeakAppDelegate : NSObject &lt;UIApplicationDelegate&gt; { UIWindow *window; Model *model; GraphicsView * gv; NSTimer * timer; } @end </code></pre> <p>The view controller itself.</p> <pre><code>#import "SbarLeakAppDelegate.h" @implementation SbarLeakAppDelegate - (void)applicationDidFinishLaunching:(UIApplication *)application { model=[Model sharedModel]; CGRect appRect; CGRect frame = CGRectInset(appRect, 0.0f, 0.0f); appRect.origin=CGPointMake(0.0, 40.0); appRect.size = CGSizeMake(200.0f, 200.0f); frame = CGRectInset(appRect, 0.0f, 0.0f); gv=[[GraphicsView alloc] initWithFrame:appRect]; [gv setFrame:frame]; [window addSubview:gv]; [gv release]; [window makeKeyAndVisible]; } -(void) viewDidAppear:(id)sender { //timer=[NSTimer scheduledTimerWithTimeInterval:.250 target:gv selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES]; } - (void)dealloc { [window release]; [super dealloc]; } @end </code></pre> <p>This code is only included for completeness but (should not) affect the question. The data source header file (just a simple integer)</p> <pre><code>#import &lt;UIKit/UIKit.h&gt; @interface Model : NSObject { int n; } @property int n; +(Model *) sharedModel; -(void) inc; @end </code></pre> <p>The data source, Model.m:</p> <pre><code>#import "Model.h" @implementation Model static Model * sharedModel = nil; + (Model *) sharedModel { if (sharedModel == nil) sharedModel = [[self alloc] init]; return sharedModel; } @synthesize n; -(id) init { self=[super init]; [NSTimer scheduledTimerWithTimeInterval:.05 target:self selector:@selector(inc) userInfo:nil repeats:YES]; return self; } -(void) inc { n++; } @end </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload