【问题标题】:Reduce Core-Graphics memory consumption on iphone减少 iPhone 上的 Core-Graphics 内存消耗
【发布时间】:2010-11-14 09:25:01
【问题描述】:

我正在编写一个程序,它会时常重绘图表。不幸的是,由于某种原因,核心图形似乎没有释放以前的图形,所以我很快就遇到了内存问题。如何强制它在每次绘制结束时释放内存?

并不是说这不是内存泄漏,因为当我关闭该视图时内存确实会被释放。我曾尝试将 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

【问题讨论】:

  • 您找到解决方案了吗?

标签: iphone memory-management uiview core-graphics


【解决方案1】:

根据 NSTimer 文档,最大时间分辨率为 50-100 毫秒...看起来您正在尝试 1 毫秒...根据规范,要求更精细分辨率的计时器不会导致内存问题,它只是不应该根据需要经常触发。不过,我怀疑这是您的问题的一部分。

NSTimer Class Reference

由于各种输入源 典型的运行循环管理, 有效解决时间 计时器的间隔被限制为开启 大约 50-100 毫秒。

【讨论】:

  • 在完整程序中,计时器每秒运行一次。这是我创建示例时的错字。所以,没有计时器不能解决内存问题/
【解决方案2】:

您用于计时器的选择器没有正确的签名。

来自Apple docs

选择器必须具有以下签名:

- (void)timerFireMethod:(NSTimer*)theTimer

您应该使用自己的计时器方法并从那里调用setNeedsDisplay。正如罗伯特所说,你应该把频率调低一点,但我认为这两个问题都不能解决你的问题。

【讨论】:

  • 说这些问题不能解决你的问题,我的意思是说:你提供的代码是正确的,没有内存问题。在别处搜索或提供更多代码。
  • 亲爱的@NikolaiRuhe,请同时提供苹果文档的链接。这真的很有帮助。但是+1的信息。 :)
【解决方案3】:

+ (Model *) sharedModel { if (sharedModel == nil) sharedModel = [[self alloc] init]; return sharedModel; } 在这个 sn-p 中,缺少自动释放。我认为这也会导致泄漏。 尝试 sharedModel = [[[self alloc] init] autorelease];

【讨论】:

  • 它可能会导致泄漏,但由于它在程序开始时只初始化一次,所以没有问题。
【解决方案4】:

您是否尝试过:self.clearsContextBeforeDrawing = YES; 中的 drawRect 方法?

【讨论】:

    猜你喜欢
    • 2013-06-13
    • 1970-01-01
    • 2023-03-18
    • 2015-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多