我遇到了一个问题,相对较大的图像似乎永远不会从内存中释放(大小为 1MB~5MB)。当用户滚动一组图像时,会调用以下代码块。大约 15 张图像后,应用程序将崩溃。有时会调用“didReceiveMemoryWarning”,有时不会调用——应用程序只会崩溃、停止、退出调试,并且不会在任何代码行上停止——什么都没有。我认为这是设备内存不足时会发生的情况?另一个问题是子类“DownloadImageOperation”似乎从未调用过“dealloc”。有任何想法吗?
获取和设置图像:
//Calling this block of code multiple times will eventually cause the
// application to crash
//Memory monitor shows real memory jumping 5MB to 20MB increments in instruments.
//Allocations tool shows #living creeping up after this method is called.
//Leaks indicate something is leaking, but in the 1 to 5 kb increments. Nothing huge.
DownloadImageOperation * imageOp = [[DownloadImageOperation alloc] initWithURL:imageURL localPath:imageFilePath];
[imageOp setCompletionBlock:^(void){
//Set the image in a UIImageView in the open UIViewController.
[self.ivScrollView setImage:imageOp.image];
}];
//Add operation to ivar NSOperationQueue
[mainImageQueue addOperation:imageOp];
[imageOp release];
下载图像操作定义:
.h 文件
#import <Foundation/Foundation.h>
@interface DownloadImageOperation : NSOperation {
UIImage * image;
NSString * downloadURL;
NSString * downloadFilename;
}
@property (retain) UIImage * image;
@property (copy) NSString * downloadURL;
@property (copy) NSString * downloadFilename;
- (id) initWithURL:(NSString *)url localPath:(NSString *)filename;
@end
.m 文件
#import "DownloadImageOperation.h"
#import "GetImage.h"
@implementation DownloadImageOperation
@synthesize image;
@synthesize downloadURL;
@synthesize downloadFilename;
- (id) initWithURL:(NSString *)url localPath:(NSString *)filename {
self = [super init];
if (self!= nil) {
[self setDownloadURL:url];
[self setDownloadFilename:filename];
[self setQueuePriority:NSOperationQueuePriorityHigh];
}
return self;
}
- (void)dealloc { //This never seems to get called?
[downloadURL release], downloadURL = nil;
[downloadFilename release], downloadFilename = nil;
[image release], image = nil;
[super dealloc];
}
-(void)main{
if (self.isCancelled) {
return;
}
UIImage * imageProperty = [[GetImage imageWithContentsOfFile:downloadFilename andURL:downloadURL] retain];
[self setImage:imageProperty];
[imageProperty release];
imageProperty = nil;
}
@end
获取图像类
.m 文件
+ (UIImage *)imageWithContentsOfFile:(NSString *)path andURL:(NSString*)urlString foundFile:(BOOL*)fileFound {
BOOL boolRef;
UIImage *image = nil;
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
if (image==nil) {
boolRef = YES;
image = [UIImage imageWithContentsOfFile:[[AppDelegate applicationImagesDirectory] stringByAppendingPathComponent:[path lastPathComponent]]];
}
if (image==nil) {
boolRef = YES;
image = [super imageWithContentsOfFile:path];
}
if (image==nil) {
//Download image from the Internet
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setTimeOutSeconds:120];
[request startSynchronous];
NSData *responseData = [[request responseData] retain];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
NSData *rdat = [[NSData alloc] initWithData:responseData];
[responseData release];
NSError *imageDirError = nil;
NSArray *existing_images = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[path stringByDeletingLastPathComponent] error:&imageDirError];
if (existing_images == nil || [existing_images count] == 0) {
// create the image directory
[[NSFileManager defaultManager] createDirectoryAtPath:[path stringByDeletingLastPathComponent] withIntermediateDirectories:NO attributes:nil error:nil];
}
BOOL write_success = NO;
write_success = [rdat writeToFile:path atomically:YES];
if (write_success==NO) {
NSLog(@"Error writing file: %@",[path lastPathComponent]);
}
image = [UIImage imageWithData:rdat];
[rdat release];
}
return image;
}
为这个巨大的代码块道歉。我真的不知道问题可能出在哪里,所以我尽量做到包容。谢谢阅读。