我有同样的问题,由于使用子类而不是类别为时已晚,我按照zoul的建议使用class_addMethod,下面是我的实现:
#import "UIImage-NSCoding.h"
#include <objc/runtime.h>
#define kEncodingKey @"UIImage"
static void __attribute__((constructor)) initialize() {
@autoreleasepool {
if (![[UIImage class] conformsToProtocol:@protocol(NSCoding)]) {
Class class = [UIImage class];
if (!class_addMethod(
class,
@selector(initWithCoder:),
class_getMethodImplementation(class, @selector(initWithCoderForArchiver:)),
protocol_getMethodDescription(@protocol(NSCoding), @selector(initWithCoder:), YES, YES).types
)) {
NSLog(@"Critical Error - [UIImage initWithCoder:] not defined.");
}
if (!class_addMethod(
class,
@selector(encodeWithCoder:),
class_getMethodImplementation(class, @selector(encodeWithCoderForArchiver:)),
protocol_getMethodDescription(@protocol(NSCoding), @selector(encodeWithCoder:), YES, YES).types
)) {
NSLog(@"Critical Error - [UIImage encodeWithCoder:] not defined.");
}
}
}
}
@implementation UIImage(NSCoding)
- (id) initWithCoderForArchiver:(NSCoder *)decoder {
if ((self = [super init]))
{
NSData *data = [decoder decodeObjectForKey:kEncodingKey];
self = [self initWithData:data];
}
return self;
}
- (void) encodeWithCoderForArchiver:(NSCoder *)encoder {
NSData *data = UIImagePNGRepresentation(self);
[encoder encodeObject:data forKey:kEncodingKey];
}
@end
到目前为止,我还没有注意到任何进一步的问题。希望它有所帮助!
[注意]
如果您使用此 UIImage 类别来归档 UIImageViewer 对象,请注意 iOS 5 中 UIImageViewer 的 NSCoding 实现似乎已损坏。 UIImageViewer 的图像属性在保存和加载后丢失,当它在 XIB 中指定时(我没有尝试查看在代码中创建 UIImageViewer 对象时是否存在相同的问题)。这已在 iOS 6 中修复。
[更新]
我将代码更改为在 +load 中添加方法而不是 initialize(),它仍然只执行一次,但更早。我目前的实现:
#import "UIImage+NSCoding.h"
#import <objc/runtime.h>
#define kEncodingKey @"UIImage"
@implementation UIImage (NSCoding)
+ (void) load
{
@autoreleasepool {
if (![UIImage conformsToProtocol:@protocol(NSCoding)]) {
Class class = [UIImage class];
if (!class_addMethod(
class,
@selector(initWithCoder:),
class_getMethodImplementation(class, @selector(initWithCoderForArchiver:)),
protocol_getMethodDescription(@protocol(NSCoding), @selector(initWithCoder:), YES, YES).types
)) {
NSLog(@"Critical Error - [UIImage initWithCoder:] not defined.");
}
if (!class_addMethod(
class,
@selector(encodeWithCoder:),
class_getMethodImplementation(class, @selector(encodeWithCoderForArchiver:)),
protocol_getMethodDescription(@protocol(NSCoding), @selector(encodeWithCoder:), YES, YES).types
)) {
NSLog(@"Critical Error - [UIImage encodeWithCoder:] not defined.");
}
}
}
}
- (id) initWithCoderForArchiver:(NSCoder *)decoder {
if (self = [super init]) {
NSData *data = [decoder decodeObjectForKey:kEncodingKey];
self = [self initWithData:data];
}
return self;
}
- (void) encodeWithCoderForArchiver:(NSCoder *)encoder {
NSData *data = UIImagePNGRepresentation(self);
[encoder encodeObject:data forKey:kEncodingKey];
}
@end