0

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

但是有 valueForKeyPath: 而没有 intForKeyPath:、stringForKeyPath: 等?

4

2 回答 2

1

AppleNSDictionary不支持名为intForKey:或的消息stringForKey:

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

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

于 2012-12-21T04:36:58.850 回答
0

您正在混合来自 2 个不同对象(实际上是 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是验证对象类型。假设你在 key 下保存了一个NSArrayof ,你误写了如下代码:NSDictionaryMDClientsKey

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

Objective-C 的动态特性意味着用户默认为该objectForKey:调用返回的对象不会NSDictionary像代码假设的那样是一个,而是一个NSArray. 下一行将尝试调用objectForKey:NSArray,这可能会引发 NSInvalidArgumentException 并导致应用程序崩溃。

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

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

随后的行将意味着您正在向 发送消息nil,这将被简单地忽略(换句话说,没有崩溃)。

另一方面,valueForKey:andvalueForKeyPath:方法是NSKeyValueCoding非正式协议的一部分。它们基本上允许一个对象通过名称访问另一个实例变量,NSString而不是通过调用一个方法。这其中的一个关键部分是需要返回对象,而不是像 or 等​​原始类型valueForKey:。事实上,如果一个对象具有像 一样的原始类型的属性,调用将自动包装它以返回一个. 因此,拥有扩展访问器并没有多大意义。valueForKeyPath:intfloatheightNSInteger[object valueForKeyPath:@"height"]NSNumber*ForKeyPath:

于 2012-12-21T05:05:58.013 回答