我正在编写一个程序,它经常重新绘制图表。不幸的是,由于某种原因,核心显卡似乎没有释放以前的图形,所以我很快遇到了内存问题。如何强制它在每次绘制结束时释放内存?
这并不是内存泄漏,因为当我关闭该 View 时内存确实会被释放。我尝试将 NSTimer 移动到代码中的多个位置,但没有成功。
以下是下面的代码,其中文件从最重要到(可能)不相关。
首先是核心文件+ header ,它经常绘制图形(在本例中为正弦波)。
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
View Controller header :
#import <UIKit/UIKit.h>
#import "GraphicsView.h"
@interface SbarLeakAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
Model *model;
GraphicsView * gv;
NSTimer * timer;
}
@end
View Controller 本身。
#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
最佳答案
您用于计时器的选择器没有正确的签名。
来自Apple docs :
The selector must have the following signature:
- (void)timerFireMethod:(NSTimer*)theTimer
您应该使用自己的计时器方法并从那里调用setNeedsDisplay
。正如罗伯特所说,您应该稍微降低频率,但我认为这些问题都不能解决您的问题。
关于iphone - 减少 iPhone 上的核心显卡内存消耗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1188685/