我是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'
任何帮助将不胜感激。 感谢。
答案 0 :(得分:10)
键是您用来访问词典中对象的方法。在代码中调用-[bookmarks setObject:... forKey...]
的每一行上都可以反转键和对象。您的案例中出现的问题是因为您尝试将NSURL对象视为NSString对象 - [bookmarks objectForKey:(NSString *)each]
- 并且字典试图通过调用-length
来获取所谓的字符串的长度,该{1}}存在于NSString中但不适用于NSURL。
如果您总是使用相同的对象构建字典,请考虑为NSDictionary
使用更紧凑的“varargs”构造函数。 (请注意,最后一个以逗号分隔的参数必须为nil - 请参阅the related documentation)您还可以将-[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
,但您正在呼叫 {{1 }} 好像是valueForKey:
,而不是 NSDictionary
。这也会导致无法识别的选择器发生类似的崩溃。 (即使对于字典对象,也应该调用-objectForKey:
; -valueForKey:
主要用于/ Cocoa Bindings,并且做额外的工作你不需要。我发现自从我们认为这令人困惑就“键值对”而言,它是......)
最后,您还可以稍微简化枚举代码。 (bookmarks
上的for-in循环枚举其键,就像NSDictionary
一样。)
以下是我建议做最后一部分的方法:
-keyEnumerator
答案 1 :(得分:3)
你的书签词典推理反转:
[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]);
}
您还可以通过[bookmarks allValues]枚举直接获取URL对象,而不是首先获取密钥(尽管您可能因其他原因需要密钥)。
答案 2 :(得分:1)
我认为你在尝试获取URL时指的是你的while循环中的错误变量(我认为你应该使用objectForKey:
选择器来获取NSDictionary的值,而不是{{1 }}):
valueForKey:
答案 3 :(得分:1)
我正在使用相同的在线课程,发现上述答案似乎都没有用,因为NSEnumerator可能无法响应objectForKey,或者因为不支持特定类型的枚举(可能不会在iPhone SDK中进行比较)到OSX我不知道)。我让它像魅力一样工作如下......
NSString *aKey;
NSEnumerator *keyEnumerator = [bookmarks keyEnumerator];
NSURL *url;
while (aKey = [keyEnumerator nextObject])
{
url = [bookmarks objectForKey:aKey];
NSLog(@"value: %@", [url absoluteURL]);
}