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