KVC: Как да тествам за съществуващ ключ

Имам нужда от малко помощ относно KVC.

Няколко думи за работния контекст:

1) iPhone се свързва (клиент) с webService, за да получи обект,

2) Използвам JSON за прехвърляне на данни,

3) Ако клиентът има точно същото съпоставяне на обекти, мога да премина през NSDictionary от JSON, за да съхраня данните в постоянното хранилище (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"

Бихте ли ми предложили как да тествам за съществуването на ключ в обекта, така че, ако ключът съществува, да мога да продължа към актуализацията на стойността, като избягвам съобщението за грешка?

Съжалявам, ако съм бил малко объркващ в моето контекстно обяснение.

Благодаря

Дарио


person Fulkron    schedule 17.09.2009    source източник


Отговори (1)


Въпреки че не мога да измисля начин да разбера какви ключове ще поддържа даден обект, можете да използвате факта, че когато зададете стойност за несъществуващ ключ, поведението по подразбиране на вашия обект е извеждане на изключение. Можете да затворите извикването на метода 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 беше добре уловен от програмата, вторият генерира изключение, подобно на вашето.

person szzsolt    schedule 08.01.2010