[英]Interrupt queue or file write operation in iOS
I work with large images on the iPhone, so saving them to disk can take several seconds, and sometimes an instruction to delete the image comes when it hasn't finished saving. 我在iPhone上处理大图像,因此将它们保存到磁盘可能要花费几秒钟的时间,有时还需要在尚未完成保存时删除图像。 I would like to interrupt the saving process and delete the file inmediatly, without waiting for it to save first, but I can't find any way to interrupt the queue or the saving operation. 我想中断保存过程并立即删除文件,而不必等待首先保存文件,但是我找不到任何方法来中断队列或保存操作。
@interface YMSavedImage : NSObject {
UIImage *image;
NSString *path;
dispatch_queue_t imageAccess;
...
}
@end
@implementation YMSavedImage
- (id)init
{
...
imageAccess = dispatch_queue_create("imageAccessQueue", NULL);
...
}
- (void)save
{
dispatch_async(imageAccess, ^(void) {
[UIImagePNGRepresentation(image) writeToFile:path atomically:YES]; // This takes several seconds.
});
}
- (void)delete
{
dispatch_sync(imageAccess, ^(void) {
if ([fileManager fileExistsAtPath:path]) {
[fileManager removeItemAtPath:path error:NULL];
}
});
}
...
@end
writeToFile:atomically:
is going to want to write all of the data to file in one shot. writeToFile:atomically:
将要writeToFile:atomically:
将所有数据写入文件。 You would be better off grabbing an NSFileHandle
and quickly writing subsections of the data, after each atomic write you could check to see if the user has requested to cancel saving. 您最好抓住NSFileHandle
并快速写入数据的子部分,在每次原子写入之后,您可以检查用户是否已请求取消保存。
I'd suggest something like: 我建议类似的东西:
- (void)save
{
dispatch_async(imageAccess, ^{
// Create an empty file to populate
[[NSFileManager defaultManager] createFileAtPath:_imageFilePath contents:nil attributes:nil];
// Grab a handle on the file
NSFileHandle *handle = [NSFileHandle fileHandleForWritingAtPath:_imageFilePath];
NSData *imageData = UIImagePNGRepresentation(_image);
// Store how long the image is
NSUInteger totalLength = [imageData length];
// Store how many chunks we should need with the set kDesiredChunkSize
NSUInteger chunks = totalLength / kDesiredChunkSize;
NSUInteger i = 0;
// Walk through the image chunk by chunk and check if we are cancelled after each atomic operation
for (i = 0; i < chunks; i++) {
[handle seekToEndOfFile];
[handle writeData:[imageData subdataWithRange:NSMakeRange(i * kDesiredChunkSize, kDesiredChunkSize)]];
if (__userCancelledSave) { // The user asked us to cancel,
[[NSFileManager defaultManager] removeItemAtPath:_imageFilePath error:nil]; // FIXME: Handle this error
return;
}
}
// Write any remaining data that's less than one chunk in size
NSUInteger sizeDifference = totalLength - (chunks * kDesiredChunkSize);
if (sizeDifference > 0) {
[handle seekToEndOfFile];
[handle writeData:[imageData subdataWithRange:NSMakeRange(chunks * kDesiredChunkSize, sizeDifference)]];
}
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.