NSDictionary 和 NSURL 的 Objective-C 问题
-
21-08-2019 - |
题
我是 Objective-C 的新手,我不知道为什么这段代码不起作用:
NSMutableDictionary *bookmarks = [NSMutableDictionary dictionaryWithCapacity:(NSUInteger) 4];
[bookmarks setObject:@"Stanford University" forKey:[NSURL URLWithString:(NSString *) @"http://www.stanford.edu"]];
[bookmarks setObject:@"Apple" forKey:[NSURL URLWithString:(NSString *) @"http://www.apple.com"]];
[bookmarks setObject:@"Berkeley" forKey:[NSURL URLWithString:(NSString *) @"http://www.berkeley.edu"]];
[bookmarks setObject:@"CS193P" forKey:[NSURL URLWithString:(NSString *) @"http://cs193p.stanford.edu"]];
NSEnumerator *browser = [bookmarks keyEnumerator];
id each;
NSURL *url;
while ((each = [browser nextObject])) {
url = [browser valueForKey:(NSString *)each];
NSLog(@"%@", [url absoluteURL]);
}
我得到的错误是:
2009-06-29 11:25:22.844 WhatATool[2102:10b] *** -[NSURL length]: unrecognized selector sent to instance 0x1072c0
2009-06-29 11:25:22.845 WhatATool[2102:10b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL length]: unrecognized selector sent to instance 0x1072c0'
任何帮助,将不胜感激。谢谢。
解决方案
A 钥匙 是你用来访问 目的 在字典里。您拨打的每条线路上的按键和对象都会颠倒过来 -[bookmarks setObject:... forKey...]
在代码中。您的情况出现问题是因为您试图将 NSURL 对象视为 NSString 对象 - [bookmarks objectForKey:(NSString *)each]
- 字典试图通过调用来获取假定字符串的长度 -length
, ,它存在于 NSString 但不存在于 NSURL 中。
如果您总是使用相同的对象构造字典,请考虑使用更紧凑的“varargs”构造函数 NSDictionary
. 。(请注意,最后一个逗号分隔的参数必须为 nil — 请参阅 相关文档)您还可以使用 -[NSDictionary dictionaryWithObjects:forKeys:]
有两个 NSArray 对象,包含 URL 和书签名称。(顺便说一句,将字符串文字转换为 NSString*
创建 NSURL 是完全没有必要的。)
NSDictionary *bookmarks = [NSDictionary dictionaryWithObjectsAndKeys:
[NSURL URLWithString:@"http://www.stanford.edu"],
@"Stanford University",
[NSURL URLWithString:@"http://www.apple.com"],
@"Apple",
[NSURL URLWithString:@"http://www.berkeley.edu"],
@"Berkeley",
[NSURL URLWithString:@"http://cs193p.stanford.edu"],
@"CS193P",
nil];
此外,您还有一个尚未提及的潜在错误: browser
是一个 NSEnumerator
, ,但你正在打电话 valueForKey:
就好像它是一个 NSDictionary
, ,而不是在 bookmarks
. 。对于无法识别的选择器来说,这也会导致类似的崩溃。(即使对于字典对象,你也应该调用 -objectForKey:
反而; -valueForKey:
主要用于/由 可可绑定, ,并执行您不需要的额外工作。我意识到这很令人困惑,因为我们用“键值对”来思考,但它就是这样......)
最后,您还可以稍微简化枚举代码。(一个 for-in 循环 NSDictionary
枚举它的键就像 -keyEnumerator
会。)
我建议如何完成最后一部分:
NSURL *url
for (NSString *key in bookmarks) {
url = [bookmarks objectForKey:key];
NSLog(@"%@", [url absoluteURL]);
}
其他提示
您有书签字典intiialization颠倒:
[bookmarks setObject:@"Stanford University" forKey:[NSURL URLWithString:(NSString *) @"http://www.stanford.edu"]];
应该是:
[bookmarks setObject:[NSURL URLWithString:(NSString *) @"http://www.stanford.edu"] forKey:@"Stanford University"];
此外,还有一个更简单的方法来做到枚举:
NSURL *url;
for ( NSString *each in [bookmarks allKeys] )
{
url = [browser objectForKey:(NSString *)each];
NSLog(@"%@", [url absoluteURL]);
}
您还可以通过枚举[书签allValues]在URL对象来获取,而不是直接获取键先出来(虽然你可能想一些其他原因的键)。
我想你想获取URL(我想你应该使用objectForKey:
选择来获得一个NSDictionary的值,而不是valueForKey:
)时,参照了错误的变量在while循环:
NSEnumerator *browser = [bookmarks keyEnumerator];
id each;
NSURL *url;
while ((each = [browser nextObject])) {
url = [bookmarks objectForKey:(NSString *)each]; // <-- bookmarks, not browser
NSLog(@"URL = %@", url);
}
我通过相同的在线课程工作,发现没有上述问题的答案似乎是在iPhone SDK无法工作或者是因为NSEnumerator可能不objectForKey响应或因为不支持枚举的特定类型的(也许比到OSX我不知道)。我得到了它像一个魅力的工作,就像如下...
NSString *aKey;
NSEnumerator *keyEnumerator = [bookmarks keyEnumerator];
NSURL *url;
while (aKey = [keyEnumerator nextObject])
{
url = [bookmarks objectForKey:aKey];
NSLog(@"value: %@", [url absoluteURL]);
}