使用 AssetsLibrary.framework 因内存压力而终止

Posted

技术标签:

【中文标题】使用 AssetsLibrary.framework 因内存压力而终止【英文标题】:Terminated due to Memory Pressure By using AssetsLibrary.framework 【发布时间】:2014-04-23 06:37:10 【问题描述】:

我正在使用 AssetsLibrary.framework 从设备库中获取图像。我成功地从库中获取了所有图像并显示在我的表格视图中。当我多次上下滚动时出现问题,我收到一个内存问题警告正在打印控制台并在一段时间后崩溃说由于内存压力而崩溃。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    static NSString *CellIdentifier = @"Cell";

    TableViewCell  *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) 
        cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    
    ALAsset *asset = [self.images objectAtIndex:indexPath.row];
    ALAssetRepresentation *representation = [asset defaultRepresentation];
    image=[UIImage imageWithCGImage:[representation fullResolutionImage]];
    [selectedAllImages addObject:image];
    url = [representation url];

    NSURL *imageURL=url;
    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    
        ALAssetRepresentation *representation = [myasset defaultRepresentation];
        fileName = [representation filename];
        cell.cellLabel.text=fileName;
    ;
    assetslibrary = [[ALAssetsLibrary alloc] init];
    [assetslibrary assetForURL:imageURL
                   resultBlock:resultblock
                  failureBlock:nil];
    [cell.cellImageView setImage:[UIImage imageWithCGImage:[asset thumbnail]]];
    return cell;

所以我需要帮助哪里出错了?谢谢

【问题讨论】:

【参考方案1】:
ALAssetRepresentation *representation = [asset defaultRepresentation];
image=[UIImage imageWithCGImage:[representation fullResolutionImage]];
[selectedAllImages addObject:image];
url = [representation url];

为什么在 cellForRowAtIndexPath 方法中得到 fullResolutionImage?并放入 selectedAllImages 数组.. 似乎 selectedAllImages 数组由 fullresolutionimages 无限填充(在滚动期间)。

assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:imageURL
               resultBlock:resultblock
              failureBlock:nil];

为什么要创建 assetslibrary 并请求相同的资产(具有相同的 url)?

我认为您应该简化您的“cellForRowAtIndexPath”方法,以便在滚动期间更轻量级。像这样的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    static NSString *CellIdentifier = @"Cell";

    TableViewCell  *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) 
        cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    
    ALAsset *asset = [self.images objectAtIndex:indexPath.row];
    ALAssetRepresentation *representation = [asset defaultRepresentation];

    cell.cellLabel.text = [representation filename];
    cell.cellImageView.image = [UIImage imageWithCGImage:[asset thumbnail]];
    return cell;

【讨论】:

谢谢 Aleksey .....你的建议真的很有帮助,我接受了你的回答。但我还有一个疑问,即我需要将所有 UIImage 保存在一个 NSMutableArray 中,我正在这样做 - > image=[UIImage imageWithCGImage:[表示fullResolutionImage]]; [selectedAllImages addObject:image];。你能告诉我如何将所有 UIImage 存储在 NSMutableArray 中 因为如果我使用这两行--> image=[UIImage imageWithCGImage:[representation fullResolutionImage]]; [selectedAllImages addObject:image];,我会收到内存问题警告。 如果你想存储所有的 UIImage,把这个循环放到一个好的地方(viewDidLoad 或其他东西 - 不是 cellforrowatindexPath): for (ALAsset *asset in images) UIImage *image = [UIImage imageWithCGImage:[ [资产默认表示] fullResolutionImage]]; [selectedAllImages addObject:image] 但我不建议这样做,因为 fullResolutionImage 可能很大,如果您保留很少的 fullResolutionImages - 应用程序可能会因内存压力而被杀死。 是的,没错。我的要求是我想将所有 UIImage 保存在 NSMutableArray 中。我该怎么做。【参考方案2】:

您从资源库加载的图像会很大。如果您尝试在表格视图中加载其中的许多,那么您将很快耗尽内存。通常的做法是从较大的图像创建缩放图像,这会占用更少的内存。

【讨论】:

以上是关于使用 AssetsLibrary.framework 因内存压力而终止的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)