tob*_*pwn 1 cocoa-touch objective-c ios
更新:此处还报告了此问题,并对原因进行了更详细的处理:
UIImageWriteToSavedPhotosAlbum只保存10个图像.为什么?
在我的情况下,错误是:"写忙" - 这似乎是与设备速度有关的问题.可能有一些解决方案涉及手动处理线程或类似问题 - 但是,受Tommy在下面的回答的启发,我序列化了图像的保存,并解决了这个问题.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
情况:
我正在尝试使用for循环将大量图像集保存到相机胶卷(图像数量取决于用户输入 - 可能是1,2,3或理论上数百).图像由一个指向NSSet(虽然我可以很容易地做NSArray),并且在for循环完成之后NSSet设置为nil.
我正在使用UIImageWriteToSavedPhotosAlbum()在分离的线程上保存图像(使用NSThread's detachNewThreadSelector:toTarget:withObject:类方法),并UIActivityIndicator在主线程上启动微调器.
问题:
当我尝试保存超过~5时,~5之后的任何图像都会在日志中输出此错误:
*** -[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
例如,假设我导出了9张图像.for循环将遍历所有9个图像(由NSLogging确认),但我将获得上述错误的4次迭代(并且只有5个图像保存到相机胶卷).
如果我在循环中添加一个断点并在每次迭代之间等待一两秒,那么它们都可以正确保存而不会抱怨.所以..
理论:
基于我的日志和观察,UIImageWriteToSavedPhotosAlbum()显然是异步运行,并且在某种程度上"太慢"无法跟上我的应用程序.
是否有一种简单的方法可以强制它同步运行(理想情况下在主线程上)?我一直在尝试为我想要保存的图像添加引用计数,但是(1)这感觉很麻烦,(2)我没有解决问题.
任何建议都会很棒.谢谢!
我使用ALAssetsLibrary和a dispatch_queue来确保按顺序保存图像:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
dispatch_queue_t queue = dispatch_queue_create("com.myApp.saveToCameraRoll", NULL);
[images enumerateObjectsUsingBlock:^(UIImage *image, NSUInteger idx, BOOL *stop) {
dispatch_async(queue, ^{
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[library writeImageToSavedPhotosAlbum:image.CGImage metadata:metaData completionBlock:^(NSURL *assetURL, NSError *writeError) {
if (writeError) {
// handle the error
}
else {
if (image == [images lastObject]) {
dispatch_async(dispatch_get_main_queue(), ^{
// perhaps indicate to the user that save has finished
});
}
}
dispatch_semaphore_signal(sema);
}];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
});
}];
Run Code Online (Sandbox Code Playgroud)