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被程序很好地捕获,第二次尝试生成与您的类似的异常。

于 2010-01-08T18:16:57.573 回答