我正在开发app下载&将图像显示为网格样式。
我将以下代码用于加载图片到我的自定义视图中。
MyView *myview = (MyView *)[self.imageListingScrollView viewWithTag:100+counter1];
myview.imgPhoto.image = [[JMImageCache sharedCache] imageForURL:myview.imageURL delegate:self];
myview.imageURL = nil;
工作正常。但它会产生内存问题。为了找到内存问题,我使用了“仪器”。
给了我内存泄漏UIImage *i = [self imageFromDiskForURL:url];
将JMImageCache.m文件转换为以下方法
- (UIImage *) imageForURL:(NSString *)url delegate:(id<JMImageCacheDelegate>)d {
if(!url) {
return nil;
}
id returner = [super objectForKey:url];
if(returner) {
return returner;
} else {
UIImage *i = [self imageFromDiskForURL:url];
if(i) {
[d imageComeFromDisk:url image:i];
[self setImage:i forURL:url];
return i;
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError *error =nil;
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url] options:NSDataWritingAtomic error:&error];
if(error){
NSLog(@"error: %@",[error description]);
}
UIImage *i = [[[UIImage alloc] initWithData:data] autorelease];
NSString* cachePath = cachePathForURL(url);
NSInvocation* writeInvocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(writeData:toPath:)]];
[writeInvocation setTarget:self];
[writeInvocation setSelector:@selector(writeData:toPath:)];
[writeInvocation setArgument:&data atIndex:2];
[writeInvocation setArgument:&cachePath atIndex:3];
NSLog(@"%@",cachePath);
data = nil;
[self performDiskWriteOperation:writeInvocation];
[self setImage:i forURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
if(d) {
if([d respondsToSelector:@selector(cache:didDownloadImage:forURL:)]) {
if(i==nil){
NSLog(@"image not get.");
}
[d cache:self didDownloadImage:i forURL:url];
}
}
});
});
return nil;
}
}
它创建高达150 MB的内存。请给我一些减少内存问题的建议。提前谢谢。
答案 0 :(得分:2)
在创建UIImage实例时使用@autoreleasepool,即使您的应用程序启用了ARC也可以避免内存泄漏。
@autoreleasepool{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSError *error =nil;
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url] options:NSDataWritingAtomic error:&error];
if(error){
NSLog(@"error: %@",[error description]);
}
UIImage *i = [[[UIImage alloc] initWithData:data] autorelease];
NSString* cachePath = cachePathForURL(url);
NSInvocation* writeInvocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(writeData:toPath:)]];
[writeInvocation setTarget:self];
[writeInvocation setSelector:@selector(writeData:toPath:)];
[writeInvocation setArgument:&data atIndex:2];
[writeInvocation setArgument:&cachePath atIndex:3];
NSLog(@"%@",cachePath);
data = nil;
[self performDiskWriteOperation:writeInvocation];
[self setImage:i forURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
if(d) {
if([d respondsToSelector:@selector(cache:didDownloadImage:forURL:)]) {
if(i==nil){
NSLog(@"image not get.");
}
[d cache:self didDownloadImage:i forURL:url];
}
}
});
});
return nil;
}