【问题标题】:Deallocating images created with UIGraphicsBeginImageContext释放使用 UIGraphicsBeginImageContext 创建的图像
【发布时间】:2013-08-13 20:02:35
【问题描述】:

我正在为 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;
}

【问题讨论】:

    标签: iphone ios objective-c animation dealloc


    【解决方案1】:

    我有类似你写的内存问题,我会在你的代码中尝试什么

    1) 使用@autoreleasepool

    将方法或循环的内容包装在@autoreleasepool { } 中以创建一个本地池,该池将在方法完成后释放。在您的情况下,在我看来,包装循环更好:

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

    2) 杀死[UIImage imageNamed]

    使用imageNamed 将准备一个缓存(取决于图像的大小),除非您遇到内存警告,否则它永远不会从内存中清除。即使您设置 myImage.image = nil,图像仍然在内存中。 XCode 的仪器工具分配视图将很好地显示它。可以这样初始化UIImage,iOS不会缓存图片:

    image = [UIImage imageWithContentsOfFile:fullpath]; 
    

    您可以在loadRetinaImageIfAvailable 下的代码中使用imageNamed

    保持这两种方法,让我们再次检查一下!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多