KVC:如何测试现有密钥

Posted

技术标签:

【中文标题】KVC:如何测试现有密钥【英文标题】:KVC: How to test for an existing key 【发布时间】:2009-09-17 01:06:47 【问题描述】:

我需要一些关于 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”的键值编码

您能否建议我如何测试对象中的键是否存在,如果键存在,我可以继续进行值更新以避免错误消息?

对不起,如果我的上下文解释有点混乱。

谢谢

达里奥

【问题讨论】:

【参考方案1】:

虽然我想不出一种方法来找出对象支持哪些键,但您可以使用这样一个事实,即当您为不存在的键设置值时,对象的默认行为是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 的尝试很好地被程序捕获,第二次尝试生成与您类似的异常。

【讨论】:

以上是关于KVC:如何测试现有密钥的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有服务器的情况下在本地测试我的 ssh 密钥

如何在 First Data Global Gateway 测试账户中获取共享密钥

如何在弗里德曼测试和维吉纳密码的上下文中知道密钥的长度和密钥本身

你如何找到你的 GitLab 主机名(以测试你的 SSH 密钥)?

测试 Windows 产品密钥是不是有效

NSManagedObject 子类 (CoreData) 中数字的 KVC 合规性