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 asNSString*to create an NSURL is completely unnecessary.)In addition, you have a lurking error that hasn’t been mentioned yet:
browseris anNSEnumerator, but you’re callingvalueForKey:as if it were anNSDictionary, rather than onbookmarks. 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
NSDictionaryenumerates its keys just like-keyEnumeratorwould.)Here’s how I’d suggest doing the last part: