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
我想访问相机胶卷中的所有照片我的代码工作正常如果我的相机胶卷中的图像很少那么应用程序工作正常但如果我有超过 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