0

メソッドを使用できるように、UIImageView の画像配列を作成しています[_myImageView startAnimating];。このようにキャッシュ(プリロード)すると、アニメーションが滑らかになることがわかりました。

しかし、Instruments では、そのゲームは割り当て解除されていますが、まだ割り当てられているメモリが多すぎます - この UIGraphicsBeginContext のものの断片がいくつかあると思います。

私はそれを正しく使用していますか、それを解放する方法は他にありますか? 前もって感謝します!

- (NSMutableArray *)generateCachedImageArrayWithFilename:(NSString *)filename extension:(NSString *)extension andImageCount:(int)count
{

    _imagesArray = [[NSMutableArray alloc] init];
    _fileExtension = extension;
    _animationImageName = filename;
    _imageCount = count;

    for (int i = 0; i < count; i++)
    {
        NSString *tempImageNames = [NSString stringWithFormat:@"%@%i", filename, i];
        NSString *imagePath = [[NSBundle mainBundle] pathForResource:tempImageNames ofType:extension];

        UIImage *frameImage = [self loadRetinaImageIfAvailable:imagePath];
        UIGraphicsBeginImageContext(frameImage.size);
        CGRect rect = CGRectMake(0, 0, frameImage.size.width, frameImage.size.height);
        [frameImage drawInRect:rect];
        UIImage *renderedImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

        [_imagesArray addObject:renderedImage];

        if (_isDoublingFrames)
        {
            [_imagesArray addObject:renderedImage];
        }
        else if (_isTriplingFrames)
        {
            [_imagesArray addObject:renderedImage];
            [_imagesArray addObject:renderedImage];
        }

        NSLog(@"filename = %@", filename);
    }

    return _imagesArray;
}


- (UIImage *)loadRetinaImageIfAvailable:(NSString *)path
{

    NSString *retinaPath = [[path stringByDeletingLastPathComponent] stringByAppendingPathComponent:[NSString stringWithFormat:@"%@@2x.%@", [[path lastPathComponent] stringByDeletingPathExtension], [path pathExtension]]];

    if ([UIScreen mainScreen].scale == 2.0 && [[NSFileManager defaultManager] fileExistsAtPath:retinaPath] == YES)
        return [[UIImage alloc] initWithCGImage:[[UIImage imageWithData:[NSData dataWithContentsOfFile:retinaPath]] CGImage] scale:2.0 orientation:UIImageOrientationUp];
    else
        return [UIImage imageWithContentsOfFile:path];
}

-(void) dealloc
{
    [_imagesArray removeAllObjects];
    _imagesArray = nil;
}
4

1 に答える 1

0

あなたが書いたのと同様のメモリの問題があり、あなたのコードで試してみることにしました

1) 使用@autoreleasepool

メソッドまたはループのコンテンツをラップして、@autoreleasepool { }メソッドが完了した後に解放されるローカル プールを作成します。あなたの状況では、ループをラップする方が良いようです:

for (int i = 0; i < count; i++)
    {
    @autoreleasepool {
    // the loop code
    ...
    }}

2) 殺す[UIImage imageNamed]

を使用imageNamedすると、(イメージのサイズに応じて) キャッシュが準備されます。このキャッシュは、メモリ警告に到達しない限り、メモリからフラッシュされることはありません。myImage.image = nil に設定しても、画像はまだメモリ内にあります。XCode の Intruments ツールの [Allocations] ビューにうまく表示されます。できることはUIImage、次のように初期化することであり、iOS は画像をキャッシュしません。

image = [UIImage imageWithContentsOfFile:fullpath]; 

imageNamedの下のコードで使用できますloadRetinaImageIfAvailable

両方のアプローチを維持して、もう一度確認してみましょう。

于 2013-08-13T21:22:13.017 に答える