Ios 使用新的照片框架保存大量照片?
我正在尝试使用iOS 8中新的Ios 使用新的照片框架保存大量照片?,ios,ios8,photosframework,Ios,Ios8,Photosframework,我正在尝试使用iOS 8中新的PHAssetChangeRequest类将一大批照片保存到照片库中。问题是,保存照片的守护进程本身似乎意外崩溃,照片数量适中(我尝试了大约500张)。有人知道如何绕过这个限制吗?守护进程本身是否存在内存使用问题?它也可能是更改块的超时限制,因为在下面的前两个日志语句之间有一个不小的间隙 assetsd守护进程不应该已经考虑到这个用例了吗,因为像这样的东西是新的Photos框架中的超级复杂模型和设计应该能够处理的吗?文档示例本身展示了保存照片的能力 以下是我的代码示
PHAssetChangeRequest
类将一大批照片保存到照片库中。问题是,保存照片的守护进程本身似乎意外崩溃,照片数量适中(我尝试了大约500张)。有人知道如何绕过这个限制吗?守护进程本身是否存在内存使用问题?它也可能是更改块的超时限制,因为在下面的前两个日志语句之间有一个不小的间隙
assetsd
守护进程不应该已经考虑到这个用例了吗,因为像这样的东西是新的Photos框架中的超级复杂模型和设计应该能够处理的吗?文档示例本身展示了保存照片的能力
以下是我的代码示例:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
for (NSURL * url in fileURLs) {
PHAssetChangeRequest * assetReq = [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:url];
}
NSLog(@"Added %d assets",fileURLs.count);
} completionHandler:^(BOOL success, NSError *error) {
if (!success){
NSLog(@"%@",error);
}
}];
这就是我的输出结果:
... Added 501 assets
... Connection to assetsd was interrupted or assetsd died
... Error Domain=NSCocoaErrorDomain Code=-1 "The operation couldn’t be completed. (Cocoa error -1.)
我甚至在PHPhotoLibrary
中尝试了同步performchange和wait
方法,但它也有同样的问题
我愿意接受建议/想法,我被卡住了!:(这并不是这个问题的真正解决方案,但它是一种变通方法。您仍然可以使用旧的库将文件成功保存到“照相机卷/照片”应用程序
ALAssetsLibrary* lib = [[ALAssetsLibrary alloc] init];
[lib writeImageDataToSavedPhotosAlbum:imageData metadata:nil
completionBlock:^(NSURL *assetURL, NSError *error)
{
// start saving your next image
}];
在循环浏览所有要保存的照片时,还建议使用AssetLibrary的单个实例。您可能还希望等待第一次图像保存完成后再开始保存下一张
然后,如果需要,您可以将生成的assetURL转换为PHAsset:
+ (PHFetchResult *)fetchAssetsWithALAssetURLs:(NSArray *)assetURLs
options:(PHFetchOptions *)options
在设备上处理大量图像即使在ARC的现代时代,在内存管理方面也必须非常小心。我有大量图像要处理(50多个图像需要调整大小),最后选择了CGImageSourceCreateTumbnailatindex()。它使用的ImageIO应该是非常高效的。我唯一剩下的问题是,由于某种原因,它仍然会保留内存,除非我将for循环包装到@autoreleasepool{}
for (ALAsset *asset in assets) {
@autoreleasepool {
resizedImage = [self thumbnailForAsset:asset maxPixelSize:JPEG_MAX_DIMENSION];
// do stuff here
}
}
我使用了这个方法,而不是从ImageAtFileUrl创建AssetRequestForAssetFromImageAtFileUrl,它非常适合10幅图像(这部分代码在
表格视图中重复:cellForRowAtIndexPath:
)
这个想法是以小批量方式进行的。
PHPhotoLibrary::performChanges
一次性提交更改请求,因此即使它能够完成,您也无法从代理或块获得任何进度更新。2017年WWDC会话附带了一个示例应用程序“”正是这样。每个performChanges
都提交了10个图像,UI更新来自performChanges
的完成块,一个信号量阻塞线程,直到一批处理完成。我在这里发布重要的代码片段:
private func addPhotos() {
let batchSize = min(photosToAdd, maxBatchSize)
if batchSize <= 0 || !active {
isAddingPhotos = false
active = false
return
}
workQueue.async {
let fileURLs = self.generateImagesAndWriteToDisk(batchSize: batchSize)
self.createPhotoLibraryAssets(with: fileURLs)
DispatchQueue.main.async {
self.addPhotos()
}
}
}
private func createPhotoLibraryAssets(with imageFileURLs: [URL]) {
photoLibrarySemaphore.wait() // Wait for any ongoing photo library
PHPhotoLibrary.shared().performChanges({
let options = PHAssetResourceCreationOptions()
options.shouldMoveFile = true
for url in imageFileURLs {
let creationRequest = PHAssetCreationRequest.forAsset()
creationRequest.addResource(with: .photo, fileURL: url, options: options)
}
}) { (success, error) in
if !success {
print("Error saving asset to library:\(String(describing: error?.localizedDescription))")
}
self.photoLibrarySemaphore.signal()
}
}
private func addPhotos(){
让batchSize=min(photosToAdd,maxBatchSize)
如果batchSize我遇到了类似的问题。我保存了4个图像,它可以工作,但是如果我再次尝试保存4个图像以替换现有的图像,我会遇到此错误。当我提出解决方案时,我会返回you@Aggressor我真的看不到“替换”的方法照片库中的现有照片。我想你可以删除并再次添加它们。这个错误似乎是由于内存过载。我减小了UIImage的文件大小,并解决了这个问题。如果你需要,我可以发布代码。不,我对减小文件大小的代码不感兴趣。我需要保存原始照片,而不是重新调整大小zed.我会想出一种不同的方法。我可以保证这是一个内存超出的错误。你有没有试过一次只做几次,然后清除缓存?比如把它分成10批,每次都清除缓存。你的DidReceiveMemory函数中有println吗?如果你全部运行500,内存函数会得到多少触发?能否在DidReceiveMemory警告中进行清除缓存调用?我遇到了同样的问题,并使用了一个OperationQueue,maxConcurrentOperationCount设置为1。您是否知道如何在使用creationRequest.addResource时将创建日期和位置数据添加到正在创建的资产中
?
private func addPhotos() {
let batchSize = min(photosToAdd, maxBatchSize)
if batchSize <= 0 || !active {
isAddingPhotos = false
active = false
return
}
workQueue.async {
let fileURLs = self.generateImagesAndWriteToDisk(batchSize: batchSize)
self.createPhotoLibraryAssets(with: fileURLs)
DispatchQueue.main.async {
self.addPhotos()
}
}
}
private func createPhotoLibraryAssets(with imageFileURLs: [URL]) {
photoLibrarySemaphore.wait() // Wait for any ongoing photo library
PHPhotoLibrary.shared().performChanges({
let options = PHAssetResourceCreationOptions()
options.shouldMoveFile = true
for url in imageFileURLs {
let creationRequest = PHAssetCreationRequest.forAsset()
creationRequest.addResource(with: .photo, fileURL: url, options: options)
}
}) { (success, error) in
if !success {
print("Error saving asset to library:\(String(describing: error?.localizedDescription))")
}
self.photoLibrarySemaphore.signal()
}
}