Re: [NSMutableDictionary setObject:forKey:] problem
Re: [NSMutableDictionary setObject:forKey:] problem
- Subject: Re: [NSMutableDictionary setObject:forKey:] problem
- From: j o a r <email@hidden>
- Date: Thu, 20 Oct 2005 00:08:06 +0200
Hej Joachim,
On 19 okt 2005, at 23.49, Joachim wrote:
Multiple errors here unfortunately...
- (void) parseXMLData
{
// Parses the XML data file and initializes the albumDict ivar
(NSMutableDictionary *)
// albumDataXMLFilePath contains the path to the AlbumData.xml
file
NSDictionary *iPhotoDict = [[NSDictionary alloc]
initWithContentsOfFile:albumDataXMLFilePath];
NSArray *iPhotoAlbums = [iPhotoDict objectForKey:@"List of
Albums"];
NSEnumerator *enumerator = [iPhotoAlbums objectEnumerator];
id iPhotoAlbumDict;
// Initialise albumDict ivar
if (albumDict)
[albumDict release];
[albumDict initWithCapacity:[iPhotoAlbums count]];
You never allocate the dictionary. You need to do this:
[albumDict autorelease];
albumDict = [[NSMutableDictionary alloc] init];
Note that alloc + init should ALWAYS be together like this! Never
alloc in one place and init in another.
The "initWithCapacity:" initializer is an optimization that you can
most often skip. Use it only if you have profiled your code and found
it to be a bottle neck.
// Step through iPhoto albums (Library, smart albums,
slideshows, books etc.)
while (iPhotoAlbumDict = [enumerator nextObject]) {
if (true || [iPhotoAlbumDict respondsToSelector:@selector
(objectForKey)]) {
// The second half of the above expression always
returns false,
// even though iPhotoAlbumDict DOES respond to the
message below
[albumDict
setObject:[[NSDictionary alloc]
initWithObjectsAndKeys:
[[iPhotoAlbumDict objectForKey:@"AlbumId"]
copy], @"AlbumId",
[[iPhotoAlbumDict objectForKey:@"Album Type"]
copy], @"AlbumType",
[[iPhotoAlbumDict objectForKey:@"PhotoCount"]
copy], @"PhotoCount",
nil]
forKey:[iPhotoAlbumDict
objectForKey:@"AlbumName"]];
Memory leak here. The dictionary added is retained by the dictionary
it's added to, so it should be released. For example like this:
[albumDict setObject: [NSDictionary dictionaryWithObjectsAndKeys:
anObj, aKey, nil] forKey: theKey];
Note how convenience class factory methods always return autoreleased
objects. Read the memory management docs for more info.
// The object is NOT added to albumDict even though
setObject: is
// supplied with a valid NSDictionary (I split the code
up to make
// sure [[NSDictionary alloc] initWith... did return
what's expected)
}
}
[iPhotoDict release];
}
Here's my questions:
1) What's wrong with my code above? Why isn't the NSDictionary
object added with the setObject:forKey: call?
See my first comment about how you allocate the dictionary.
2) Why does [iPhotoAlbumDict respondsToSelector:@selector
(objectForKey)] always return false? ([iPhotoAlbumDict class]
returns NSCFDictionary.)
Because you misspelled the selector, it should be @selector
(objectForKey:)
3) Am I handling memory correctly in my code? No leaks etc? I'm
still struggling to understand how Objective-C memory management
works.
See comment above.
Finally, does NSDictionary read the whole file into memory in the
initWithContentsOfFile: call or does it just scan the file later at
the given entry levels I specify in my code? The AlbumData.xml file
can get quite big, but I don't want to use NSXMLParser as it
involves way too much code.
The "initWithContentsOfFile:" methods present in several classes are
really simple methods. They solve the problem in the simplest way
possible, by reading and parsing the entire file at once.
j o a r
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden