我已经四处看看并在此处找到了结束答案:
但这仅适用于用户创建的自定义对象。我的问题是序列化“SKProduct”,它是一个非NSCoding兼容的派生类。具体来说,我遇到的确切错误:
-[SKProduct encodeWithCoder:]: unrecognized selector sent to instance 0x4027160
有没有人有类似的经历?
答案 0 :(得分:2)
我会在这个答案前面说这可能是一种更简单的方法;但归档和取消归档期间的类替换是您可以采取的一种方法。
在归档期间,您可以选择设置符合NSKeyedArchiverDelegate
协议的委托。所有方法都是可选的。代理在编码期间收到消息archiver:willEncodeObject:
消息。如果您希望在归档期间替换类,则可以创建替换对象并将其返回。否则只返回原始对象。
在您的情况下,您可以为SKProduct
创建一个“影子对象”,它封装了您感兴趣的序列化原始类的所有属性。然后在归档期间替换该类。在取消归档期间,您可以撤消该过程并返回SKProduct
为了便于说明,这是一个例子。请注意,我已经省略了反向替换部分 - 但如果您阅读NSKeyedUnarchiverDelegate
上的文档,我认为这很清楚。
#import <Foundation/Foundation.h>
@interface NoncompliantClass:NSObject
@property (nonatomic,assign) NSInteger foo;
@end
@implementation NoncompliantClass
@synthesize foo = _foo;
@end
@interface CompliantClass:NSObject <NSCoding>
@property (nonatomic,assign) NSInteger foo;
@end
@implementation CompliantClass
@synthesize foo = _foo;
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeInteger:self.foo forKey:@"FooKey"];
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super init];
if( !self ) { return nil; }
_foo = [coder decodeIntegerForKey:@"FooKey"];
return self;
}
@end
@interface ArchiverDelegate:NSObject <NSKeyedArchiverDelegate>
@end
@implementation ArchiverDelegate
- (id)archiver:(NSKeyedArchiver *)archiver willEncodeObject:(id)object {
NSString *objClassName = NSStringFromClass([object class]);
NSLog(@"Encoding %@",objClassName);
if( [object isMemberOfClass:[NoncompliantClass class]] ) {
NSLog(@"Substituting");
CompliantClass *replacementObj = [CompliantClass new];
replacementObj.foo = [object foo];
return replacementObj;
}
return object;
}
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
NoncompliantClass *cat1 = [NoncompliantClass new];
NoncompliantClass *cat2 = [NoncompliantClass new];
NSArray *herdableCats = [NSArray arrayWithObjects:cat1,cat2,nil];
ArchiverDelegate *delegate = [ArchiverDelegate new];
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver setDelegate:delegate];
[archiver encodeObject:herdableCats forKey:@"badKitties"];
[archiver finishEncoding];
}
}
此日志:
2012-09-18 05:24:02.091 TestSerialization[10808:303] Encoding __NSArrayI
2012-09-18 05:24:02.093 TestSerialization[10808:303] Encoding NoncompliantClass
2012-09-18 05:24:02.093 TestSerialization[10808:303] Substituting
2012-09-18 05:24:02.094 TestSerialization[10808:303] Encoding NoncompliantClass
2012-09-18 05:24:02.094 TestSerialization[10808:303] Substituting