ALAssetsLibrary 从相机胶卷应用程序崩溃访问所有照片 1000 +

ALAssetsLibrary accessing all photos 1000 + from camera roll app crashes

我想访问相机胶卷中的所有照片我的代码工作正常如果我的相机胶卷中的图像很少那么应用程序工作正常但如果我有超过 1000 张照片然后应用程序崩溃这是我的代码

ALAssetsLibrary *al = [[ALAssetsLibrary alloc] init];

     [al enumerateGroupsWithTypes:ALAssetsGroupAll

                      usingBlock:^(ALAssetsGroup *group, BOOL *stop)
     {
         NSMutableArray *arrImages=[[NSMutableArray alloc]init];
         NSString *albumName = [group valueForProperty:ALAssetsGroupPropertyName];
         if (albumName !=nil) {


         [arrGroupsNames addObject:albumName];
         [group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
          {
              if (asset)
              {

                  UIImage *img=[self imageForAsset:asset];


                  [arrImages addObject:img];

              }
          }
           ];

         [arrGroups addObject:arrImages];
         }



         [self.tableVieww reloadData];

     }



                    failureBlock:^(NSError *error)
     {
         // User did not allow access to library
         NSLog(@"error");
      }
     ];

这里是 return 图像来自 ALAsset

的函数
-(UIImage*) imageForAsset:(ALAsset*) aAsset{

    ALAssetRepresentation *rep;

    rep = [aAsset defaultRepresentation];

    return [UIImage imageWithCGImage:[rep fullResolutionImage]];
}

问题是,为用户相机胶卷中的每张照片创建 UIImage,您将 运行 内存不足。这很容易是 1000 多张图片,使用 fullResolutionImage 将获得最大版本的图片。

要解决此问题,请将 ALAsset 放入数组中,而不是组成 UIImage 的数组。然后仅在屏幕上需要时从 ALAsset 创建 UIImage

您正在将所有 1000+ UIImage 存储在一个数组中,而您的内存不足。我有同样的问题,我的是 2000 多张图片,使用下面的实现对我有用。

我还建议,您在显示图像时使用 [asset thumbnail],特别是如果它只是为了 UITableViewCell 或其他不需要图像的完整分辨率的目的。

这里有一个解决方案:

//First you need to declare `ALAssetsLibrary *al` as a global variable in the class
//
//like this:
//
//.h
@interface YOURCLASS : UIViewController
{
  ALAssetsLibrary *al;
}

@end
//
//or inside your .m
//
@interface YOURCLASS () 
{
  ALAssetsLibrary *al;
}

---

// you need to do this to check if 'al' is already declared and to declare once
if (al == nil)
    al = [[ALAssetsLibrary alloc] init];

[al enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
    ...

    [group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
    {
      if (asset)
      {
         /*//your code
          UIImage *img=[self imageForAsset:asset];

          [arrImages addObject:img];
        */

        //instead of storing the actual UIImage object just store the `asset` in your array
        //like
        [arrImages addObject:asset];

      }
    }];

    ...

} 
failureBlock:^(NSError *error) 
{
  // User did not allow access to library
  NSLog(@"error");
}];

在你的 table 委托中 cellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  ...

  //you need to get the image using the stored asset
  //like:

  //cast what's inside the array
  ALAsset *asset = (ALAsset *)self.arrGroups[indexPath.row];

  //self.arrGroups[indexPath.row];
  //if just for example i dont know how you access your datas

  cell.imageView.image = [UIImage imageWithCGImage:[asset thumbnail]];

  //getting the full resolution of the image
  //[UIImage imageWithCGImage:[[asset defaultRepresentation] fullResolutionImage]]
  //
  //or you can simply use what you already have `[self imageForAsset:asset]`
  //cell.imageView.image = [self imageForAsset:asset];

  ...
}

希望对您有所帮助,干杯!

        -(void)loadCameraPhotos{

            [MBProgressHUD showHUDAddedTo:self.view animated:YES];
            ALAssetsLibrary *al = [[ALAssetsLibrary alloc] init];

             [al enumerateGroupsWithTypes:ALAssetsGroupAll

                              usingBlock:^(ALAssetsGroup *group, BOOL *stop)
             {
                 NSMutableArray *arrImages=[[NSMutableArray alloc]init];
                 NSString *albumName = [group valueForProperty:ALAssetsGroupPropertyName];
                 if (albumName !=nil) {


                 [arrGroupsNames addObject:albumName];
                 [group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
                  {
                      if (asset)
                      {

                         // if (arrImages.count<7) {



                          //UIImage *img=[self imageForAsset:asset];


                          [arrImages addObject:asset];
                          //}else
                            //  *stop=YES;


                       }
                  }
                   ];

                 [arrGroups addObject:arrImages];
                 }


                 [MBProgressHUD hideAllHUDsForView:self.view animated:YES];
                 [self.tableVieww reloadData];

             }



                            failureBlock:^(NSError *error)
             {
                 // User did not allow access to library
                 NSLog(@"error");
              }
             ];
    }

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{


    static NSString *cellIdentifier = @"PhotoSelectionTableViewCell";
    PhotoSelectionTableViewCell* cell = (PhotoSelectionTableViewCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil) {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"PhotoSelectionTableViewCell" owner:nil options:nil];
        for(id currentObject in topLevelObjects) {
            if ([currentObject isKindOfClass:[UITableViewCell class] ]){
                cell = (PhotoSelectionTableViewCell *)currentObject;
                break;
            }
        }
    }

    NSArray *arrtemp=[arrGroups objectAtIndex:indexPath.section];
    cell.lblTitle.text=[arrGroupsNames objectAtIndex:indexPath.section];
    cell.lblCount.text=[NSString stringWithFormat:@"%lu",(unsigned long)arrtemp.count];

    ALAsset *asset = (ALAsset *)[arrtemp lastObject];

    cell.imgViewThumbnail.image=[UIImage imageWithCGImage:[asset thumbnail]];;

    return cell;


}

我真的怀疑这个 solution.NSCache 如果你想尽快加载太多照片,必须使用这个你可以在这个存储库中看到详细信息 https://github.com/johnil/JFImagePickerController