JMImagecache中的内存泄漏

时间:2013-03-29 06:42:37

标签: iphone objective-c xcode automatic-ref-counting

我正在开发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的内存。请给我一些减少内存问题的建议。提前谢谢。

1 个答案:

答案 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;

}