我已经环顾四周,在这里找到了关闭的答案:
但这仅适用于用户创建的自定义对象。我的问题是序列化“SKProduct”,这是一个不符合 NSCoding 的派生类。具体来说,我遇到的确切错误:
-[SKProduct encodeWithCoder:]: unrecognized selector sent to instance 0x4027160
有没有人有类似的经历?
我已经环顾四周,在这里找到了关闭的答案:
但这仅适用于用户创建的自定义对象。我的问题是序列化“SKProduct”,这是一个不符合 NSCoding 的派生类。具体来说,我遇到的确切错误:
-[SKProduct encodeWithCoder:]: unrecognized selector sent to instance 0x4027160
有没有人有类似的经历?
我将通过说可能有一种更简单的方法来作为这个答案的开头;但是归档和取消归档期间的类替换是您可以采取的一种方法。
在归档期间,您可以选择设置符合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