2009-07-27 5 views
4

나는 그래프를 자주 그리는 프로그램을 작성 중이다. 불행히도 그것은 어떤 이유로 코어 그래픽이 이전 그래픽을 풀어 놓는 것처럼 보이지 않기 때문에 메모리 문제를 빨리 겪게됩니다. 각 추첨이 끝날 때 어떻게 강제로 메모리를 해제 할 수 있습니까?iphone의 코어 그래픽 메모리 사용량 줄이기

해당보기를 닫을 때 메모리가 해제되므로 메모리 누수가 아닙니다. NSTimer를 코드의 여러 위치로 이동시켜 보았습니다.

아래의 코드는 파일이 가장 중요한 것부터 (잠재적으로) 관련성이없는 것입니다.

먼저 그래픽 (이 경우 사인파)을 매번 그리는 코어 파일 + 헤더가 있습니다.

GraphicsView.h

#import <UIKit/UIKit.h> 
#import "Model.h" 

@interface GraphicsView : UIView 
{ 
    Model * model; 
} 
@end 

GraphicsView.m

#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<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 

뷰 컨트롤러 헤더 :

#import <UIKit/UIKit.h> 
#import "GraphicsView.h" 


@interface SbarLeakAppDelegate : NSObject <UIApplicationDelegate> 
{ 
    UIWindow *window; 
    Model *model; 
    GraphicsView * gv; 
    NSTimer * timer; 
} 

@end 

뷰 컨트롤러 자체.

#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 

이 코드는 완전성을 위해 포함되었지만 질문에 영향을 주어서는 안됩니다. 데이터 소스 헤더 파일 (단순한 정수)

#import <UIKit/UIKit.h> 


@interface Model : NSObject 
{ 
    int n; 
} 

@property int n; 
+(Model *) sharedModel; 
-(void) inc; 
@end 

데이터 소스 Model.m :

#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 
+0

해결 방법을 찾으셨습니까? –

답변

0

는 NSTimer 문서에 따르면, 최대 시간 해상도는 50-100ms이다 .. 그것은 당신이 1ms 동안 노력하고있는 것처럼 보입니다 ... 스펙에 따르면 메모리 문제가 발생하지 않아야하는 것보다 더 정밀한 해상도를 요구하는 타이머가 필요하면 자주 발사해서는 안됩니다. 그래도 그것이 당신 문제의 일부라고 생각합니다. 때문에 다양한 입력

NSTimer Class Reference

는 전형적인 운전 루프가 관리하는 타이머 간격 50~100 밀리 초 정도의 한정되는 시간 유효 해상도를 소싱.

+0

전체 프로그램에서 타이머는 1 초에 1 회 실행됩니다. 제가 예제를 만들 때 이것은 오타였습니다. 그래서 타이머가 메모리 문제를 해결하지 못합니다/ –

2

타이머에 사용하는 선택기의 서명이 올바르지 않습니다. Apple docs에서

는 :

- (void)timerFireMethod:(NSTimer*)theTimer 

당신은 타이머에 대한 자신 만의 방법을 사용하고 거기에서 setNeedsDisplay를 호출해야합니다 :

선택기에는 다음의 서명이 필요합니다. 로버트가 말했듯이, 당신은 빈도를 약간 줄여야하지만, 나는이 문제들 중 하나라도 당신의 문제를 해결할 것이라고 생각하지 않습니다.

+0

그건 중요한 질문이 아닙니다. –

+0

... 정확성을 위해 노력한다면 귀중한 정보가 될 것입니다. –

+0

이러한 문제로 문제가 해결되지 않는다고 말하면서 말씀 드렸습니다. 제공 한 코드가 정확하고 메모리 문제가 없습니다. 다른 곳에서 검색하거나 더 많은 코드를 제공하십시오. –

0

+ (Model *) sharedModel { if (sharedModel == nil) sharedModel = [[self alloc] init]; return sharedModel; } 이 스 니펫에는 autorelease가 없습니다. 이것은 또한 누출로 이어질 것입니다. sharedModel = [[[self alloc] init] autorelease];

+0

누수가 발생할 수 있지만 프로그램의 시작 부분에 한 번만 초기화되므로 문제가되지 않습니다. –

1

당신이 시도해 봤어으로 시도 다음 drawRect 방법 self.clearsContextBeforeDrawing = YES;을?