为什么会有 valueForKey: 和 intForKey:, stringForKey: 等。
但是有 valueForKeyPath: 而没有 intForKeyPath:、stringForKeyPath: 等?
为什么会有 valueForKey: 和 intForKey:, stringForKey: 等。
但是有 valueForKeyPath: 而没有 intForKeyPath:、stringForKeyPath: 等?
AppleNSDictionary
不支持名为intForKey:
或的消息stringForKey:
。
也许您正在使用一些将这些消息添加到类别中的第三方库。您可以询问该库的作者,为什么她不包含消息的密钥路径版本。
也许你在想NSUserDefaults
,不是NSDictionary
。 NSUserDefaults
了解integerForKey:
和stringForKey:
。 NSUserDefaults
不适用于存储大型复杂结构。它旨在存储小而简单的数据。
您正在混合来自 2 个不同对象(实际上是 1 个对象和一个非正式协议)的方法名称:NSUserDefaults
和NSKeyValueCoding
非正式协议。
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 下保存了一个NSArray
of ,你误写了如下代码:NSDictionary
MDClientsKey
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:
int
float
height
NSInteger
[object valueForKeyPath:@"height"]
NSNumber
*ForKeyPath: