Difference between objectForKey and valueForKey?
objectForKey和valueForKey有什么区别?我在文档中查阅了这两个文档,我觉得它们是一样的。
objectForKey:是一种NSDictionary方法。NSDictionary是一个类似于NSArray的集合类,除了不使用索引之外,它使用键来区分项目。密钥是您提供的任意字符串。两个对象不能有相同的键(就像NSArray中的两个对象不能有相同的索引一样)。
valueForKey:是一种kvc方法。它适用于任何班级。valueForKey:允许您使用名称字符串访问属性。因此,例如,如果我有一个Account类和一个accountNumber类的属性,我可以执行以下操作:
1 2 3 4 5 6
| NSNumber *anAccountNumber = [NSNumber numberWithInt:12345];
Account *newAccount = [[Account alloc] init];
[newAccount setAccountNumber:anAccountNUmber];
NSNumber *anotherAccountNumber = [newAccount accountNumber]; |
使用kvc,我可以动态访问属性:
1 2 3 4 5 6
| NSNumber *anAccountNumber = [NSNumber numberWithInt:12345];
Account *newAccount = [[Account alloc] init];
[newAccount setValue:anAccountNumber forKey:@"accountNumber"];
NSNumber *anotherAccountNumber = [newAccount valueForKey:@"accountNumber"]; |
这些是等价的语句集。
我知道你在想:哇,但讽刺地说。kvc看起来并不那么有用。事实上,它看起来"冗长"。但是当你想在运行时改变一些事情时,你可以做很多在其他语言中更困难的酷的事情(但这超出了你的问题范围)。
如果你想了解更多关于kvc的知识,有很多教程,尤其是在ScottStevenson的博客上。您还可以查看nskeyValueCoding协议参考。
希望有帮助。
- 根据键是否以@符号开头,ValueForkey对于nsDictionary对象的行为不同。
- 对象分叉:接受任何对象作为键,而不仅仅是字符串。唯一的要求是密钥支持nscopying协议。
- 这两点都是绝对正确的。nsdictionaries是一种特殊情况,您不必为键使用字符串。我并没有真正深入到这两者的微妙之处,因为似乎asker只是需要一个简单的比较。
- 我很惊讶没有人通过指出valueforkey来纠正这个问题:从技术上讲,它不允许您访问相应的实例变量,而是允许(可以)管理实例变量的访问器方法。
- 警告:ValueForkey的速度可能非常慢——它目前是我iPad应用程序的一个主要瓶颈,速度太慢,以至于用"标准"字典替换它会使应用程序明显更快。iOS上的kvc出了点问题,我再也不会使用它了——这不值得性能下降,而且无论如何都要重新编写它。这是在calayers上使用带有nsstring值的nsstring键。仪器显示"caObject-ValueForkey"占总运行时间的25%!
- @亚当,听起来很可怕。从7开始你又试过了吗?如果是的话,从那以后情况有变吗?
- 然而,有时,有一个实际的差异,我还不清楚。valueForKey在sogo-3.1.4的代码中不起作用,它试图在context对象(EXCEPTION: NAME:NSInvalidArgumentException REASON:-[WOContext ASProtocolVersion]: unrecognized selector sent to instance上调用一个不可用的"方法"ASProtocolVersion,而objectForKey起作用(这是在代码中查询context对象的常用方法)。参见github.com/inverse-inc/sogo/pull/217/files
当执行valueForKey:操作时,需要给它一个nsstring,而objectForKey:可以将任何nsobject子类作为键。这是因为对于键值编码,键始终是字符串。
事实上,文档规定,即使您给valueForKey:一个nsstring,它也会无论如何调用objectForKey:,除非字符串以@开头,在这种情况下,它调用[super valueForKey:],这可能会调用valueForUndefinedKey:,这可能会引发异常。
- 你能告诉我你所指的文件的链接吗?谢谢您。
- @??????????:就在这里
这里有一个很好的理由尽可能使用objectForKey:,而不使用带有未知密钥的valueForKey:-valueForKey:,会抛出NSUnknownKeyException,说"这个类不是密钥的键值编码兼容"。
- 很高兴知道"value for key:有一个未知的键会抛出nsunknownkeyException,它说"这个类不是键值编码兼容的键"
如前所述,objectForKey:数据类型为:(id)aKey,而valueForKey:数据类型为:(NSString *)key。
例如:
1 2 3 4 5 6 7
| NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObject:@"123"],[NSNumber numberWithInteger:5], nil];
NSLog(@"objectForKey : --- %@",[dict objectForKey:[NSNumber numberWithInteger:5]]);
//This will work fine and prints ( 123 )
NSLog(@"valueForKey : --- %@",[dict valueForKey:[NSNumber numberWithInteger:5]]);
//it gives warning"Incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString *'" ---- This will crash on runtime. |
因此,valueForKey:只取字符串值,是kvc方法,而objectForKey:则取任何类型的对象。
objectForKey中的值将由同一类对象访问。