为什么objC中没有* ForKeyPath?

时间:2012-12-21 04:00:58

标签: objective-c nsdictionary

为什么有valueForKey:和intForKey:,stringForKey:等等。

但是有valueForKeyPath:并且没有intForKeyPath:,stringForKeyPath:等等?

2 个答案:

答案 0 :(得分:1)

Apple的NSDictionary不支持名为intForKey:stringForKey:的邮件。

也许您正在使用某些第三方库在类别中添加这些消息。您可以询问该库的作者为何不包含消息的密钥路径版本。

也许你在考虑NSUserDefaults,而不是NSDictionaryNSUserDefaults了解integerForKey:stringForKey:NSUserDefaults不用于存储大型复杂结构。它用于存储小而简单的数据。

答案 1 :(得分:0)

您正在混合来自2个不同对象(实际上是1个对象和1个非正式协议)的方法名称:NSUserDefaultsNSKeyValueCoding非正式协议。

NSUserDefaults已存在多年,而键值编码和键值观察仅在OS X 10.3之后出现。

NSUserDefaults处理存储与属性列表兼容的对象(NSData,NSDate,NSString,NSArray和NSDictionary),以便在应用程序启动之间保持持久性。应用程序通常需要存储非对象类型值(如BOOL或int),但只支持对象,因此这些便捷方法(intForKey:boolForKey:等)允许更简洁的方法来保存它们。例如,以下代码行

[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:MDFirstLaunchKey];

变为:

[[NSUserDefaults standardUserDefaults] setBool:NO forKey:MDFirstLaunchKey];

相应的“get”方法允许更简洁的代码来获取非对象类型值。

NSUserDefaults中这些方法的另一个目的是验证对象类型。假设您在密钥NSArray下保存了NSDictionary MDClientsKey,并且您错误地编写了以下代码:

NSDictionary *client = [userDefaults objectForKey:MDClientsKey];
NSString *name = [client objectForKey:@"name"];

Objective-C的动态特性意味着对象用户默认值将返回,objectForKey:调用将不是代码假定的NSDictionary,而是NSArray。后续行将尝试在NSArray上调用objectForKey:,这可能会引发NSInvalidArgumentException并导致应用程序崩溃。

如果您改为使用dictionaryForKey:,则NSUserDefaults会返回nil

NSDictionary *client = [userDefaults dictionaryForKey:MDClientsKey];
NSString *name = [client objectForKey:@"name"];

后续行将意味着您向nil发送了一条消息,该消息被忽略(换句话说,没有崩溃)。

另一方面,valueForKey:valueForKeyPath:方法是NSKeyValueCoding非正式协议的一部分。它们基本上允许一个对象使用NSString按名称访问另一个对象的实例变量,而不是必须调用方法。其中一个关键部分是valueForKey:valueForKeyPath:需要返回对象,而不是基本类型,如intfloat等。事实上,如果一个对象有一个{ {1}} height这样的基本类型的属性,调用NSIntegerautomatically wrap它返回[object valueForKeyPath:@"height"]。因此,拥有扩展的NSNumber访问器并没有多大意义。