views:

2401

answers:

2

Still learning Objective-C / iPhone SDK here. I think I know why this wasn't working but I just wanted to confirm.

In awakeFromNib, if I use [[NSMutableDictionary alloc] initWithObjects:...] it actually allocates (iPhone) system memory with this NSMutableDictionary data, but when I use [NSMutableDictionary dictionaryWithObjects:...] it is only available in the stack right?

For example, in the future if I try to access myMutableDict from a button press via IBAction, the myMutableDict object may have been freed, causing my app to crash, even though I have defined it like so in my .h file, and synthesized it:

@property (nonatomic, retain) NSMutableDictionary *myMutableDict;

For some reason changing to [[NSMutableDictionary alloc] initWithObjects:...] fixed this.

+11  A: 

+dictionaryWithObjects: returns an autoreleased dictionary
-initWithObjects: you must release yourself

if you want the dictionary to persist as a instance variable, you should create it with an init method or retain an autoreleased version, either way you should be sure to release it in your dealloc method

An excellent resource on this topic is the Memory Management Programming Guide for Cocoa.

cobbal
so basically any time you synthesize an object for use across your entire project or whatever, for example, you would always want to use initWithDictionary so it doesn't get randomly released on you, correct?
taber
correct, or [[NSMutableDictionary dictionaryWithObjects…] retain] is equivalent
cobbal
ok sounds good, thanks!
taber
Another +1 for Apple's Memory Management guide. It's long and sometimes a bit dull, but you need to trudge through it at least once to know what's going on. Once you wrap your head around retain counts, it's a lot smoother sailing.
Michael Grinich
Also, +dictionaryWithObjects: calls -initWithObjects: and autoreleases the resulting instance before returning it.
Quinn Taylor
cobbal: Not exactly, as with that solution, the object will have a retain count of 2: one is from its creation and will be subtracted when the autorelease comes due, and the other is from your explicit retain. (And this, new Cocoa programmers, is why you shouldn't care about `retainCount`—it does *not* tell you how many objects own the object!)
Peter Hosey
+3  A: 

To expand on the other answer, there are a few subtle things you're missing.

For one, there are no such thing as stack objects in Objective-C. All objects live on the heap, and the one form is, as mentioned, "autoreleased".

Also, you're probably setting your instance variable directly, bypassing the memory management from your @synthesize'd accessor and mutator. Instead of this:

myMutableDict = [NSMutableDictionary dictionaryWithObjects:...];

you should probably be saying

self.myMutableDict = [NSMutableDictionary dictionaryWithObjects:...];

or else you have to manually add the retain or remove the autorelease, as you've discovered.

Again, read the memory management guide. It explains all of this in exhaustive detail.

Jim Puls
will do, thank you!
taber
i was definitely doing that, by the way. oops. thanks again.
taber