2

我是 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'

任何帮助,将不胜感激。谢谢。

4

4 回答 4

10

是您用来访问字典中的对象的键。-[bookmarks setObject:... forKey...]在代码中调用的每一行,您的键和对象都颠倒了。在您的情况下出现问题是因为您试图将 NSURL 对象视为 NSString 对象——[bookmarks objectForKey:(NSString *)each]并且字典试图通过调用 来获取假定字符串的长度-length,它存在于 NSString 但不存在于 NSURL。

如果您总是用相同的对象构造字典,请考虑为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];

此外,您还有一个尚未提及的潜在错误:browseris an NSEnumerator,但您调用valueForKey:时好像它是 an NSDictionary,而不是 on bookmarks。对于无法识别的选择器,这也会导致类似的崩溃。(即使对于字典对象,您也应该调用-objectForKey:-valueForKey:主要用于/由Cocoa Bindings使用,并且会执行您不需要的额外工作。我意识到这很令人困惑,因为我们是根据“键值对”来考虑的,但是它是...)

最后,您还可以稍微简化枚举代码。(一个 for-in 循环NSDictionary就像枚举它的键一样-keyEnumerator。)

这是我建议做最后一部分的方法:

NSURL *url
for (NSString *key in bookmarks) {
    url = [bookmarks objectForKey:key];
    NSLog(@"%@", [url absoluteURL]);
}
于 2009-06-29T18:55:20.577 回答
4

您已反转书签字典初始化:

[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 对象,而不是先取出键(尽管您可能出于其他原因想要键)。

于 2009-06-29T18:35:39.083 回答
1

我认为您在尝试获取 URL 时在 while 循环中引用了错误的变量(并且我认为您应该使用objectForKey:选择器来获取 NSDictionary 的值,而不是valueForKey:):

NSEnumerator *browser = [bookmarks keyEnumerator];
id each;
NSURL *url;
while ((each = [browser nextObject])) {
    url = [bookmarks objectForKey:(NSString *)each]; // <-- bookmarks, not browser
    NSLog(@"URL = %@", url);
}
于 2009-06-29T18:35:54.090 回答
1

I'm working through the same online classes and found that none of the answers above seem to work either because NSEnumerator may not respond to objectForKey or because the particular type of enumeration is not supported (perhaps not in the iPhone SDK as compared to OSX i don't know). I got it to work like a charm as follows though...

NSString *aKey;
NSEnumerator *keyEnumerator = [bookmarks keyEnumerator];
NSURL *url;

while (aKey = [keyEnumerator nextObject])
{
    url = [bookmarks objectForKey:aKey];
    NSLog(@"value: %@", [url absoluteURL]);
}
于 2009-08-15T14:12:11.977 回答