22

タイプのセットSearchEntity(カスタムオブジェクト)を含むオブジェクト(カスタムオブジェクト)をシリアル化しようとしました。NSMutableDictionaryCategoryEntity

1SearchEntity<NSCoding>を含む:1 NSMutableDictionary(パラメーター)CategoryEntities<NSCoding>文字列と数字のみを含むXを含むパラメーター。

SearchEntity encodeWithCoderのこの行[encoder encodeObject:parameters forKey:kPreviousSearchEntityKey];で、「毎回GDB:Interruptedが表示され、エラーメッセージや例外などは発生せず、GDB:Interruptedだけが表示されます。

これはの実装でSearchEntityあり、パラメータはNSMutableDictionary

#pragma mark -
#pragma mark NSCoding delegate methods

- (void) encodeWithCoder:(NSCoder*)encoder 
{
    //encode all the values so they can be persisted in NSUserdefaults
    if (parameters) 
        [encoder encodeObject:parameters forKey:kPreviousSearchEntityKey]; //GDB:Interrupted!
}

- (id) initWithCoder:(NSCoder*)decoder 
{
    if (self = [super init]) 
    {
        //decode all values to return an object from NSUserdefaults in the same state as when saved     
        [self setParameters:[decoder decodeObjectForKey:kPreviousSearchEntityKey]];
    }
    return self;
}

またCategoryEntity、NSCodingプロトコルを実装し、次のようになります。

- (void) encodeWithCoder:(NSCoder*)encoder 
{
    //encode all the values so they can be persisted in NSUserdefaults
    [encoder encodeObject:ID forKey:kIDKey];
    [encoder encodeObject:text forKey:kTextKey];
    [encoder encodeObject:category forKey:kCategoryKey];
    [encoder encodeObject:categoryIdentifierKey forKey:kCategoryIdentifierKey];
}

- (id) initWithCoder:(NSCoder*)decoder 
{
    if (self = [super init]) {

        //decode all values to return an object from NSUserdefaults in the same state as when saved
        [self setID:[decoder decodeObjectForKey:kIDKey]];
        [self setText:[decoder decodeObjectForKey:kTextKey]];
        [self setCategory:[decoder decodeObjectForKey:kCategoryKey]];
        [self setCategoryIdentifierKey:[decoder decodeObjectForKey:kCategoryIdentifierKey]];
    }
    return self;
}

次のように、NSUserDefaultsのラッパーからエンコードしようとします。

+ (void) setPreviousSearchParameters:(SearchParameterEntity*) entity
{
    if (entity) 
    {
        //first encode the entity (implements the NSCoding protocol) then save it
        NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:entity];
        [[self defaults] setObject:encodedObject forKey:kPreviousSearchKey];
        [[self defaults] synchronize];      
    }
}

+ (SearchParameterEntity*) getPreviousSearchParameters
{
    //retrieve the encoded NSData object that was saved, decode and return it
    SearchParameterEntity *entity = nil;
    NSData *encodedObject = [[self defaults] objectForKey:kPreviousSearchKey];

    if (encodedObject)
        entity = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];

    return entity;
}

SearchEntityをシリアル化するように要求すると、'parameters' mutableDictionaryオブジェクトのシリアル化が開始され、NSCoderは辞書に含まれるCategoryEntitiesで "encode"を呼び出し、それらはすべて正しいエンコードされたオブジェクトで応答すると考えていました。

ただし、コンソールの下部にGDB:Interruptedが表示されます。

どうすればこれをデバッグできますか?

そして、私のアプローチは間違っています、NSDataですべてのレベルのエンコーディングをラップする必要がありますか?

追伸 ResultEntityを含むNSArrayを使用してまったく同じことを行いますCategoryEntities。問題なくエンコードされるため、NSMutableDictionaryだけが突出していると思います。

4

3 に答える 3

1

あなたが投稿したコードは間違っていないようです。私は、あなたが省略したいくつかの詳細について最善の推測を行いました.コードが正しくエンコード/デコードされることを示すのに十分なボイラープレートを備えたコードを含むテストプログラムから、成功した結果が得られました.

(コマンドラインから: を使用してコンパイルし、:gcc -framework foundation test.m -o testで実行できます./test。)

あなたの質問に関して、これをデバッグするにはどうすればよいですか、次のようなアプローチをお勧めします。

  • (一時的に) コードをできるだけシンプルに変更します。たとえば、parametersプロパティをプレーンに変更し、NSString最初にそれが正しく機能することを確認できます。
  • エラーが再び発生し始めるまで、一度に 1 つの新しいプロパティを導入しながら、ゆっくりと複雑さを追加します。最終的には、厄介なデータがどこから来ているのかを絞り込みます。

悲しいかな、これがアプリの他の場所でのメモリの管理ミスが原因で発生している場合、このコード自体をデバッグしても何も解決しない可能性があります。エンコーディング用に受信する各データのメモリが正しく管理されていることを (手動で) 検証してみてください。

すでにCore Dataを使用している場合は、オブジェクト IDのみをユーザーのデフォルトに保持し、それに基づいてオブジェクト グラフを復元することを検討できます。(参照: NSCoding を使用した NSManagedObject のアーカイブ)。

于 2011-10-03T05:37:25.497 に答える
0

最初に NSMutableArray をバイパスすることをお勧めします。SearchEntity に CategoryEntity が 1 つだけ含まれるようにして、それが機能するかどうかを確認します。

あなたが投稿したコードは良さそうです。より詳細なコンテキストを提供してください。

オブジェクトのエンコーディングについては、次のファイルが役立ちます: DateDetailEntry

于 2011-11-04T03:57:59.983 に答える
-1

NSKeyedArchiver でオブジェクトをアーカイブする際の問題は、変更可能なオブジェクトをエンコードできないことですNSArrayNSDictionaryNSStringNSDateNSNumber、およびNSData (およびそれらのサブクラスの一部) のインスタンスのみをシリアル化できます。

したがって、 SearchEntity メソッドではencodeWithCoder:、 NSMutableDictionary から NSDictionary を作成してから、不変のものをエンコードしてみてください。

if (parameters) {
    NSDictionary *dict = [NSDictionary dictionaryWithDictionary:parameters];
    [encoder encodeObject:dict forKey:kPreviousSearchEntityKey];
}

また、initWithCoder:メソッドで、エンコードされた不変のものから NSMutableDictionary を作成してみてください。

NSDictionary *dict = [decoder decodeObjectForKey:kPreviousSearchEntityKey];
     [self setParameters:[NSMutableDictionary dictionaryWithDictionary:dict]];

また、ディクショナリ内のすべてのオブジェクトparametersが NSCoding プロトコルに準拠していることを確認し、それらすべてがencodeWithCoder:メソッド内で不変オブジェクトのみをエンコードしていることを確認します。

問題が解決することを願っています。

于 2011-09-22T06:50:26.370 に答える