2013-10-25 6 views
7

私はすべての午後に、このクラスのデコーディングが失敗した理由を突きつけようと壁に頭をぶつけて過ごしました。クラスはFooオブジェクトのNSArrayであるプロパティを持っています。 FooはNSSecureCodingに準拠しており、私は正常にそのクラスをコード化してデコードしました。私はinitWithCoderでエラーを受け取りました:クラスFooを解読できませんでした。いくつかの実験を通して、私はinitWithCoderに[Foo class]を追加する必要があることを発見しました。多分これは、同じ問題を抱えている他の誰かを助けるでしょう。私の質問は、なぜこれが必要なのでしょうか?私はこれがリンゴのドキュメンテーションに必要であるという示唆は見つかりませんでした。NSSecureCodingでNSArrayをデコードするときの奇妙な振る舞い

#import "Foo.h" 

@interface MyClass : NSObject <NSSecureCoding> 
@property (nonatomic) NSArray *bunchOfFoos; 
@end 

@implementation MyClass 

static NSString *kKeyFoo = @"kKeyFoo"; 

+ (BOOL) supportsSecureCoding 
{ 
    return YES; 
} 

- (void) encodeWithCoder:(NSCoder *)encoder 
{ 
    [encoder encodeObject:self.bunchOfFoos forKey:kKeyFoo]; 
} 

- (id) initWithCoder:(NSCoder *)decoder 
{ 
    if (self = [super init]) 
    { 
     [Foo class]; // Without this, decoding fails 
     _bunchOfFoos = [decoder decodeObjectOfClass:[NSArray class] forKey:kKeyFoo]; 
    } 
    return self; 
} 

@end 
+0

あなたが達成しようとしていることは、Fooクラスでエンコード/デコードを実装する必要があると思います。 – zaph

+0

はい、FooはNSSecureCodingに準拠していると言いました。つまり、そのクラスでエンコード/デコードが実装されています。 –

答えて

2

私はこれを理解したかもしれないと思います。 [Foo class]という行がなければ、このファイルのFooクラスへの参照はありません。このため、私はコンパイラがFooクラスを最適化していると考えて、配列内のFooオブジェクトをデコードできません。そこにフークラスを持つことでこれを防ぐことができます。

3

まだこれに苦しんでいる人のために:@Ben Hの解決策は私の問題を解決しませんでした。そして、私は次のエラーメッセージ持つ保つ:

がキャッチされない例外により「NSInvalidUnarchiveOperationException」にアプリを終了し、理由:> 'の値のキーのための 『NS.objectsはにClassA『』予期しないクラスでした』。許可されるクラスは '{(
NSArray
)}'です。

最後に、私はカスタムクラスのためにそれを実現しました。

- (id)decodeObjectOfClasses:(NSSet *)classes forKey:(NSString *)key 

をそして、あなたは上記の機能にNSArrayに可能なすべてのクラスのNSSetを渡すために:あなたは代わりにdecodeObjectOfClasses次の関数を使用する必要があります! @Ben Hがなぜ機能の外に[Foo class]を追加するだけで問題を解決できるのかよく分かりません。たぶんそれはコンパイラの問題です。しかし、とにかく、彼の解決策がうまくいかなければ、これも試してみてください。

+1

これは私のために働いた。 – Gomfucius

+0

@Gomfuciusが助けてくれることを喜んで承ります –

+0

ありがとう!これは機能します。 –

3

私はちょうど似たような問題に遭遇しました。それは奇妙で非常に時間がかかりました。私は、クラスがNSSecureCodedになるように、Specta/Expectaで正しくテストしたかったのです。だから私は、デコード時にクラスを指定する必要に応じてすべてを実装しました。

value for key 'key' was of unexpected class 'MyClass'. Allowed classes are '{(
    MyClass 
)}'. 

テストはそのようなものを見て:

平野NSCoding(requiresSecureCoding = NO)、テストが成功したものの
MyClass *myClassInstance = ... 
NSMutableData *data = [NSMutableData data]; 
NSKeyedArchiver *secureEncoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 
[secureEncoder setRequiresSecureCoding:YES]; // just to ensure things 

NSString *key = @"key"; 
[secureEncoder encodeObject:myClassInstance forKey:key]; 
[secureEncoder finishEncoding]; 

NSKeyedUnarchiver *secureDecoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; 
[secureDecoder setRequiresSecureCoding:YES]; 
MyClass *decodedInstance = [secureDecoder decodeObjectOfClass:[MyClass class] forKey:key]; // exception here 
[secureDecoder finishDecoding]; 

...expect... 

、NSSecureCodingテストが失敗まま私の試験の終わりに、私は奇妙な例外が発生しました。予想されるように、そのすべての私のテストは、オブジェクトが作成された成功した後

[secureDecoder setClass:[MyClass class] forClassName:NSStringFromClass([MyClass class])]; 

:臨床試験の広大な範囲の後、私は、1行だけをそのための解決策を見つけました。

なぜそれが起こったのか分かりませんが、私の推測では、Ben Hと表示されていないと思われ、NSClassFromString(@"MyClass")のようなものが使用されています。上記のコードはAppDelegateで正常に機能しました。 MyClassは開発中の開発ポッドからのものでした。