0

画像をダウンロードしてグリッド スタイルに表示するアプリを開発しています。

次のコードを使用して、画像をカスタム ビューに読み込みます。

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 のメモリを作成します。このメモリの問題を軽減するための提案をお願いします。前もって感謝します。

4

1 に答える 1

2

アプリケーションで ARC が有効になっている場合でも、このように UIImage インスタンスを作成するときに @autoreleasepool を使用して、メモリ リークを回避します。

@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;

}
于 2013-03-29T06:50:45.533 に答える