KVC:如何测试现有密钥

时间:2009-09-17 01:06:47

标签: objective-c cocoa key-value-coding

我需要一些关于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”不符合密钥值编码

你能否建议我如何测试对象中是否存在密钥,这样,如果密钥存在,我可以继续进行值更新,避免出现错误信息吗?

很抱歉,如果我的上下文解释中有点混乱。

由于

的Dario

1 个答案:

答案 0 :(得分:3)

虽然我无法想出找出对象支持哪些键的方法,但您可以使用以下事实:当您为不存在的键设置值时,对象的默认行为是throw an exception。您可以将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

这对于密钥stuff应该是KVC兼容的,但没有别的。

如果您从以下程序访问此类:

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