Objective-C Learning: Need advice on how to populate NSMutableDictionary
I am teaching myself Objective-C using several resources, one of which is the iPhone Stanford class available through iTunes U (last class of 2010).
One of my homework assignments asked me to populate a mutable dictionary with a predefined list of keys and values (URLs). I managed to compose the code, but looking at it I keep thinking that the approach to what I am trying to do is probably better suited to me:
- Fill NSMutableDictionary with predefined keys and values
- List the dictionary keys and check each key to see if it starts with "Stanford"
- If it meets the criteria, write down both the key and the value
I would really appreciate any feedback on how I can improve what I have put together. I am a beginner's definition, but I really like the Objective-C learning problem.
void bookmarkDictionary () {
NSMutableDictionary* bookmarks = [NSMutableDictionary dictionary];
NSString* one = @"Stanford University",
*two = @"Apple",
*three = @"CS193P",
*four = @"Stanford on iTunes U",
*five = @"Stanford Mall";
NSString* urlOne = @"http://www.stanford.edu",
*urlTwo = @"http://www.apple.com",
*urlThree = @"http://cs193p.stanford.edu",
*urlFour = @"http://itunes.stanford.edu",
*urlFive = @"http://stanfordshop.com";
NSURL* oneURL = [NSURL URLWithString:urlOne];
NSURL* twoURL = [NSURL URLWithString:urlTwo];
NSURL* threeURL = [NSURL URLWithString:urlThree];
NSURL* fourURL = [NSURL URLWithString:urlFour];
NSURL* fiveURL = [NSURL URLWithString:urlFive];
[bookmarks setObject:oneURL forKey:one];
[bookmarks setObject:twoURL forKey:two];
[bookmarks setObject:threeURL forKey:three];
[bookmarks setObject:fourURL forKey:four];
[bookmarks setObject:fiveURL forKey:five];
NSString* akey;
NSString* testString = @"Stanford";
for (akey in bookmarks) {
if ([akey hasPrefix:testString]) {
NSLog(@"Key: %@ URL: %@", akey, [bookmarks objectForKey:akey]);
}
}
}
Thanks for your help!
a source to share
Your code looks correct and you are correct to think there is a better way. You can reduce the number of temporary variables and use (non-mutable) NSDictionary
instead NSMutableDictionary
by choosing an initializer for the task:
NSDictionary *bookmarks = [NSDictionary dictionaryWithObjectsAndKeys:
[NSURL urlWithString:@"http://www.stanford.edu"], @"Stanford University",
[NSURL urlWithString:@"http://www.apple.com"], @"Apple",
//...etc...,
nil
];
Note that -[NSDictionary dictionaryWithObjectsAndKeys:]
, like all Cocoa factory methods, it creates an instance autoreleased
. If you intend to retain ownership of the dictionary for the current scope, you must retain
return an instance or use alloc/initWithObjectsAndKeys:
.
If the assignment (oddly) requires a replaceable dictionary instead, you can of course use +[NSMutableDictionary dictionaryWithObjectsAndKeys:]
.
I prefer the clearer search form you use. Some may feel that (if you are at 10.6) it is better to use a more functional form:
[bookmarks enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
if([key hasPrefix:testString]) { NSLog(@"Key: %@ URL: %@", key, value); }
}];
a source to share
I would also recommend using a plist for static data (which it seems you have). If you define a plist, you can load it directly into the NSDictionary with very little code.
You can read about it here Plist to Dictionary
a source to share