2

私はすでに周りを見回して、ここでクローズの答えを見つけました:

iOSでカスタムオブジェクトを保存/シリアル化する正しい方法

ただし、これはユーザーが作成したカスタムオブジェクトにのみ適用されます。私の問題は、NSCodingに準拠していない派生クラスである「SKProduct」のシリアル化です。具体的には、私が遭遇した正確なエラー:

-[SKProduct encodeWithCoder:]: unrecognized selector sent to instance 0x4027160

誰かが同じような経験をしていますか?

4

1 に答える 1

2

おそらくもっと簡単な方法があると言って、この答えの前に置きます; ただし、アーカイブおよびアーカイブ解除中のクラス置換は、実行できる1つのアプローチです。

アーカイブ中に、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
于 2012-09-18T10:32:18.357 に答える