我使用以下方法请求许多照片并将它们添加到数组中供以后使用:
-(void) fetchImages{
self.assets = [[PHFetchResult alloc]init];
PHFetchOptions *options = [[PHFetchOptions alloc] init];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
self.assets = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:options];
self.photosToVideofy = [[NSMutableArray alloc]init];
CGSize size = CGSizeMake(640, 480);
PHImageRequestOptions *photoRequestOptions = [[PHImageRequestOptions alloc]init];
photoRequestOptions.synchronous = YES;
for (NSInteger i = self.firstPhotoIndex; i < self.lastPhotoIndex; i++)
{
PHAsset *asset = self.assets[i];
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeAspectFit options:photoRequestOptions resultHandler:^(UIImage *result, NSDictionary *info) {
if (result) {
[self.photosToVideofy addObject:result];
}
}];
}
NSLog(@"There are %lu photos to Videofy", (unsigned long)self.photosToVideofy.count);
}
当照片数量少于50时,此功能正常。在内存跳转到150-160mb后,我收到消息Connection to assetsd was interrupted or assetsd died
,应用程序崩溃。
在得到我想要的资产后,如何从内存中释放资产(PHFetchResult)?(我需要吗?)
我希望能够添加多达150张照片。
有任何想法吗?
感谢
答案 0 :(得分:2)
您不应将PHFetchResult的结果放入数组中。 PHFetchResult的想法是指向照片库中的许多图像,而不是将它们全部存储在RAM中(我不确定它是如何做到的)只是像数组一样使用PHFetchResult对象,它处理内存问题您。例如,将collectionViewController直接连接到PHFetchResult对象,并使用PHImageManager仅为可见单元格等请求图像。
来自苹果文档: &#34;然而,与NSArray对象不同,PHFetchResult对象根据需要从Photos库动态加载其内容,即使在处理大量结果时也能提供最佳性能。&#34; https://developer.apple.com/library/ios/documentation/Photos/Reference/PHFetchResult_Class/
答案 1 :(得分:1)
你必须设置
photoRequestOptions.synchronous = NO;
而不是
photoRequestOptions.synchronous = YES;
为我工作,iOS 10.2
答案 2 :(得分:0)
你在fetchImages方法中的代码需要一些重构,看看这个建议:
-(void) fetchImages {
PHFetchOptions *options = [[PHFetchOptions alloc] init];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
PHFetchResult *assets = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:options];
self.photosToVideofy = [[NSMutableArray alloc] init];
CGSize size = CGSizeMake(640, 480);
PHImageRequestOptions *photoRequestOptions = [[PHImageRequestOptions alloc] init];
photoRequestOptions.synchronous = YES;
for (NSInteger i = self.firstPhotoIndex; i < self.lastPhotoIndex; i++)
{
PHAsset *asset = assets[i];
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeAspectFit options:photoRequestOptions resultHandler:^(UIImage *result, NSDictionary *info) {
if (result) {
[self.photosToVideofy addObject:result];
}
}];
}
NSLog(@"There are %lu photos to Videofy", (unsigned long)self.photosToVideofy.count);
}
但问题是内存消耗。让我们做一些计算。
单张图像,使用ARGB和每像素4个字节:
640x480x4 = 1.2MB
现在,您想要在RAM 150中存储图像,所以:
150x1.2MB = 180MB
例如,如果您使用大约300 MB的数据,那么512 MB的iPhone 4会崩溃,但如果其他应用程序也消耗大量RAM,则可能会减少。
我认为,您应该考虑将图像存储到文件而不是RAM。
答案 3 :(得分:0)
这可能是有意的(无法查看代码的其余部分),但是self.photosToVideofy永远不会发布:因为你在一个块中访问它,你传递的对象块([PHImageManager defaultManager])将始终具有对数组的引用。
在完成图像后,尝试明确清除阵列。阵列本身仍然不会被释放,但它包含的对象将会(或者如果它们没有在其他任何地方被引用)。
最好的解决方案是从块中删除数组。但是,这需要更改代码的逻辑。