Unarchive UIImage 对象在 iOS 8 上使用 NSKeyedUnarchiver 返回 CGSizeZero 图像

Posted

技术标签:

【中文标题】Unarchive UIImage 对象在 iOS 8 上使用 NSKeyedUnarchiver 返回 CGSizeZero 图像【英文标题】:Unarchive UIImage object returns CGSizeZero image using NSKeyedUnarchiver on iOS 8 【发布时间】:2014-10-06 09:39:55 【问题描述】:

我有这段代码在 ios 7 上运行:

NSData *imageData = [NSKeyedArchiver archivedDataWithRootObject:self.imageView.image];
UIImage *imageCopy = [NSKeyedUnarchiver unarchiveObjectWithData:imageData];
NSLog(@"%@",NSStringFromCGSize(imageCopy.size));

但在 iOS 8 上,imageCopy 的大小始终为零。当我存档UIImageView 时也会发生同样的事情,未存档的imageView 的图像大小为零。我发现在 iOS 7 中,UIImage 标头是这样的:

UIImage : NSObject <NSSecureCoding, NSCoding>

但在 iOS 8 上是:

UIImage : NSObject <NSSecureCoding>

iOS 8 上似乎缺少 NSCoding 协议。我必须对实际图像数据进行编码:UIImagePNGRepresentation(self.imageView.image) 而不是图像,以确保我得到一个好的图像。

有人知道为什么会这样吗?是为了向后兼容吗?我注意到在 iOS 早期版本中 UIImage 不符合 NSCoding

【问题讨论】:

至少对我来说,这段代码在 iOS8/Xcode6 上运行良好。我只为 nil 的图像得到 0, 0,对于所有其他图像,我得到 640, 640 等 不适合我,我在 iOS8 上使用 Xcode6 版本 6.0.1,你呢? 版本 6.0.1 (6A317) 并在 iPhone 5s 上试用。 在 xcode 6.4 上有同样的问题。下面的解决方案有效 【参考方案1】:

UIImage : NSObject &lt;NSSecureCoding&gt; 不是问题,因为NSSecureCoding 继承了NSCoding

无论如何,我确认问题可以用以下代码重现:

UIImage *img = [UIImage imageNamed: @"myImage"];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:img];
UIImage *imgCopy = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"%@, %@", imgCopy, NSStringFromCGSize(imgCopy.size)); // -> (null), 0, 0

另一方面,以下代码按预期工作:

UIImage *img = [UIImage imageNamed: @"myImage"];
UIImage *img2 = [UIImage imageWithCGImage:img.CGImage scale:img.scale orientation:img.imageOrientation];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:img2];
UIImage *imgCopy = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"%@, %@", imgCopy, NSStringFromCGSize(imgCopy.size)); // -> <UIImage: 0x7fa013e766f0>, 50, 53

我不知道为什么,也许是错误?

我认为,这与iOS8中引入的imageAssettraitCollection属性有关

【讨论】:

真的!我得到了和你一样的结果,另一种方法有效,我首先在imageView上发现了问题,解压后,imageView副本的图像大小为零,你认为是什么原因造成的?我的问题中的代码使用了self.imageView.image,图像来自缓存,而不是来自资源包。 好吧,我不知道,对不起:) 我花了半天时间。掌心。并且回答有效!

以上是关于Unarchive UIImage 对象在 iOS 8 上使用 NSKeyedUnarchiver 返回 CGSizeZero 图像的主要内容,如果未能解决你的问题,请参考以下文章

UIImage知识点汇总

iOS获取UIImage内存大小

Archiving

unarchive模块

自定义类 Unarchive 在 Cocoa Swift 中为零

ansibel的unarchive模块