是否可以使用 NSKeyedArchiver 来存储动画 UIImage?

Posted

技术标签:

【中文标题】是否可以使用 NSKeyedArchiver 来存储动画 UIImage?【英文标题】:Is it possible to use NSKeyedArchiver to store an animated UIImage? 【发布时间】:2016-02-08 02:13:10 【问题描述】:

我使用从网络服务器下载的帧加载了一张图片。

NSArray* frames = [self fetchFramesFromServer];
imageView.image = [UIImage animatedImageWithImages:frames duration:1.0];

每当我尝试归档这些帧时,编码函数都会返回 NO:

BOOL success = [NSKeyedArchiver archiveRootObject:(frames) toFile:archivePath];

每当我尝试归档图像时,编码函数也会返回 NO:

BOOL success = [NSKeyedArchiver archiveRootObject:(imageView.image) toFile:archivePath];

这是否可能,或者我是否遗漏了一些需要从包中加载 UIImage、以 png 格式或非动画形式的 archiveRootObject 警告?

仅供参考,在调试器中打印出来的存档路径是

NSPathStore2 * @"/var/mobile/Containers/Data/Application/E475E3C1-4E3F-43D6-AD66-0F98320CF279/Library/Private Documents/assets/a/b/c.archive"   0x000000012c555a60

更新:

我将动画的各个帧存储在一个 for 循环中,但我得到以下信息:

+ (void) saveImage:(UIImage*)inputImage
    withSuffix:(NSString*)fileSuffix

if (inputImage == nil) 
    NSLog(@"ERROR: input image is nil!");
    return;


// strip away intermediate folders to avoid over-nesting
// ex: __F1/MF/FR/1_MF_FR_Animation_a1.png
// ===> 1_MF_FR_Animation_a1.png
NSString* suffixStub = [MyDatabase stubOfFilepath:fileSuffix];

NSURL* url = [MyDatabase folderURL];
NSURL* imageURL = [url URLByAppendingPathComponent:suffixStub];

NSData* pngData = UIImagePNGRepresentation(inputImage);
[NSKeyedArchiver archiveRootObject:pngData toFile:imageURL.path];
pngData = nil;

NSLog(@"Image %@ successfully saved!", fileSuffix);
 

但是在 NSKeyedArchiver 行,我得到“malloc: *** error for object 0x178202340: Freeing unallocated pointer”

【问题讨论】:

不存档图像。将图像存储在磁盘上并归档它们的名称。 所以在我的示例中,如果我通过 AFNetworking 获取图像,它已经将文件写入文档文件夹 [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:@"/imageName .png"];那么您建议归档 NSString filePath,然后在取消归档文件名后,使用 [NSData dataWithContentsOfURL:unarchivedPath] 从该位置读取? 仅供参考,我还发现我的示例不起作用,因为archivePath 包含一堆嵌套文件夹。如果我只是附加到文档 URL 一次,它就可以工作...... 其实,为什么还要存档名字呢?如果我可以从我想要的图像名称生成路径,我可以归档一个 NSNumber 布尔值 @0 或 @1 来判断图像是否已下载......对吗? 【参考方案1】:

首先将您的图像转换为 NSData,然后尝试归档它

NSData* data = UIImagePNGRepresentation(imageView.image);
BOOL success = [NSKeyedArchiver archiveRootObject:data toFile:archivePath];

NSArray 的情况下,只有当数组的所有对象都符合NSCoding 协议时,才能进行归档。如果您的数组有自定义对象,请参阅 Custom object archiving 了解如何符合 NSCoding

更新

如果您的数组对象是CGRect 类型的帧,您可以使用NSStringFromCGRect()CGRectFromString() 来存储然后检索它们。

【讨论】:

我在 for 循环中对每一帧都这样做了: + (void) saveImage:(UIImage*)inputImage withSuffix:(NSString*)fileSuffix; // 剥离中间文件夹以避免过度嵌套 NSString* suffixStub = [MyDatabase stubOfFilepath:fileSuffix]; NSURL* url = [MyDatabase folderURL]; NSURL* imageURL = [url URLByAppendingPathComponent:suffixStub]; NSData* pngData = UIImagePNGRepresentation(inputImage); [NSKeyedArchiver archiveRootObject:pngData toFile:imageURL.path];但是 malloc: *** 对象 0x178202340 的错误:释放未分配的指针

以上是关于是否可以使用 NSKeyedArchiver 来存储动画 UIImage?的主要内容,如果未能解决你的问题,请参考以下文章

NSKeyedArchiver 和 iCloud

NSKeyedArchiver 线程安全吗?

Xcode-project 不使用 NSKeyedArchiver 存档,但 Playground 可以

NSKeyedArchiver.unarchiveObject Swift 3 iOS 10

NSData 从 NSKeyedArchiver 到 NSString

NSKeyedArchiver