我在 UIView 中有一行 UILabel 文本,它通过 NSTimer 定期更新。该代码应该每隔一段时间在屏幕底部附近写入一个状态项。数据来自其控制之外。
我的应用程序很快就会耗尽内存,因为似乎 UILabel 没有被释放。似乎从未调用 dealloc 。
这是我的代码的一个非常压缩的版本(为清楚起见,删除了错误检查等。):
文件:SbarLeakAppDelegate.h
#import <UIKit/UIKit.h>
#import "Status.h"
@interface SbarLeakAppDelegate : NSObject
{
UIWindow *window;
Model *model;
}
@end
文件:SbarLeakAppDelegate.m
#import "SbarLeakAppDelegate.h"
@implementation SbarLeakAppDelegate
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
model=[Model sharedModel];
Status * st=[[Status alloc] initWithFrame:CGRectMake(0.0, 420.0, 320.0, 12.0)];
[window addSubview:st];
[st release];
[window makeKeyAndVisible];
}
- (void)dealloc
{
[window release];
[super dealloc];
}
@end
文件:Status.h
#import <UIKit/UIKit.h>
#import "Model.h"
@interface Status : UIView
{
Model *model;
UILabel * title;
}
@end
File:Status.m 这就是问题所在。UILabel 似乎没有被释放,字符串也很可能。
#import "Status.h"
@implementation Status
- (id)initWithFrame:(CGRect)frame
{
self=[super initWithFrame:frame];
model=[Model sharedModel];
[NSTimer scheduledTimerWithTimeInterval:.200 target:self selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];
return self;
}
- (void)drawRect:(CGRect)rect
{
title =[[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 12.0f)];
title.text = [NSString stringWithFormat:@"Tick %d", [model n]] ;
[self addSubview:title];
[title release];
}
- (void)dealloc
{
[super dealloc];
}
@end
文件:Model.h(这个和下一个是数据源,因此仅出于完整性考虑。)它所做的只是每秒更新一个计数器。
#import <Foundation/Foundation.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:1 target:self selector:@selector(inc) userInfo:nil repeats:YES];
return self;
}
-(void) inc
{
n++;
}
@end