2

KVC について少し助けが必要です。

操作コンテキストについてのいくつかの言葉:

1) iPhone は (クライアント) を webService に接続してオブジェクトを取得します。

2) JSON を使用してデータを転送しています。

3) クライアントがまったく同じオブジェクト マッピングを持っている場合、JSON から NSDictionary を繰り返し処理して、データを永続ストア (coreData) に格納できます。そのために、次のコード フラグメントを使用しています (すべてのデータが NSString であると仮定します)。

NSDictionary *dict = ... dictionary from JSON

NSArray *keyArray = [dict allKeys]; //gets all the properties keys form server

for (NSString *s in keyArray){

[myCoreDataObject setValue:[dict objectForKey:s] forKey:s];  //store the property in the coreData object 

}

今私の問題....

4) サーバーが 1 つの新しいプロパティを持つオブジェクトの新しいバージョンを実装するとどうなりますか? データをクライアントに転送し、クライアントが保存バージョン レベルでない場合 (つまり、「古い」オブジェクト マッピングをまだ使用しているということです) '存在しないキーに値を割り当てようとします...そしてメッセージが表示されます:

エンティティ「myOldObject」は、キー「myNewKey」のキー値コーディングに準拠していません

オブジェクトにキーが存在するかどうかをテストする方法を教えてください。キーが存在する場合、エラーメッセージを回避して値の更新に進むことができますか?

コンテキストの説明で少し混乱していたら申し訳ありません。

ありがとう

ダリオ

4

1 に答える 1

3

オブジェクトがサポートするキーを見つける方法は思いつきませんが、存在しないキーの値を設定すると、オブジェクトのデフォルトの動作が例外をスローするという事実を利用できます。これらのエラーを処理するために、setValue:forKey:メソッド呼び出しを@try/ブロックで囲むことができます。@catch

オブジェクトの次のコードを検討してください。

@interface KVCClass : NSObject {
    NSString *stuff;
}

@property (nonatomic, retain) NSString *stuff;

@end

@implementation KVCClass

@synthesize stuff;

- (void) dealloc
{
    [stuff release], stuff = nil;

    [super dealloc];
}

@end

これは、キーの KVC 準拠である必要がありますが、それ以外はstuff何もありません。

次のプログラムからこのクラスにアクセスする場合:

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    KVCClass *testClass = [[KVCClass alloc] init];

    [testClass setValue:@"this is the value" forKey:@"stuff"];

    NSLog(@"%@", testClass.stuff);

    // Error handled nicely
    @try {
        [testClass setValue:@"this should fail but we will catch the exception" forKey:@"nonexistentKey"];
    }
    @catch (NSException * e) {
        NSLog(@"handle error here");
    }

    // This will throw an exception
    [testClass setValue:@"this will fail" forKey:@"nonexistentKey"];

    [testClass release];
    [pool drain];
    return 0;
}

次のようなコンソール出力が表示されます。

2010-01-08 18:06:57.981 KVCTest[42960:903] this is the value
2010-01-08 18:06:57.984 KVCTest[42960:903] handle error here
2010-01-08 18:06:57.984 KVCTest[42960:903] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<KVCClass 0x10010c680> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key nonexistentKey.'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00007fff851dc444 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x00007fff866fa0f3 objc_exception_throw + 45
    2   CoreFoundation                      0x00007fff85233a19 -[NSException raise] + 9
    3   Foundation                          0x00007fff85659429 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 434
    4   KVCTest                             0x0000000100001b78 main + 328
    5   KVCTest                             0x0000000100001a28 start + 52
    6   ???                                 0x0000000000000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
Abort trap

これは、キーにアクセスする最初の試みがnonexistentKeyプログラムによってうまくキャッチされたことを示しています.2番目の試みはあなたのものと同様の例外を生成しました.

于 2010-01-08T18:16:57.573 に答える