I am new to Objective-C and I have no clue why this code is not working:
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]);
}
The error I get is:
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'
Any help would be appreciated. Thanks.
A key is what you use to access an object in the dictionary. You have your keys and objects reversed on every line you call -[bookmarks setObject:... forKey...] in the code. The problem in your case arises because you're trying to treat NSURL objects as NSString objects — [bookmarks objectForKey:(NSString *)each] — and the dictionary is trying to get the length of the supposed string by calling -length, which exists for NSString but not for NSURL.
If you're always constructing a dictionary with the same objects, consider using a more compact "varargs" constructor for NSDictionary. (Note that the last comma-separated argument must be nil — see the related documentation) You can also use -[NSDictionary dictionaryWithObjects:forKeys:] with two NSArray objects, containing the URLs and the bookmark names. (Incidentally, casting string literals as NSString* to create an NSURL is completely unnecessary.)
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];
In addition, you have a lurking error that hasn't been mentioned yet: browser is an NSEnumerator, but you're calling valueForKey: as if it were an NSDictionary, rather than on bookmarks. That will cause a similar crash for an unrecognized selector, too. (Even for dictionary objects, you should call -objectForKey: instead; -valueForKey: is used mostly for/by Cocoa Bindings, and does extra work you don't need. I realize it's confusing since we think in terms of "key-value pairs", but there it is...)
Finally, you can also simplify the enumeration code somewhat. (A for-in loop on an NSDictionary enumerates its keys just like -keyEnumerator would.)
Here's how I'd suggest doing the last part:
NSURL *url
for (NSString *key in bookmarks) {
url = [bookmarks objectForKey:key];
NSLog(@"%@", [url absoluteURL]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With