• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Loading a Dictionary
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Loading a Dictionary


  • Subject: Re: Loading a Dictionary
  • From: Jason Harris <email@hidden>
  • Date: Thu, 3 Feb 2005 19:11:09 -0700

Quick memory management primer ahead:

When you put objects into a dictionary, they are retained. This is equivalent to calling:
[myObject retain];
When they're removed from the dictionary, they're released. Equivalent to:
[myObject release];
When the retainCount reaches zero, the object is deallocated. If it's an object that you wrote, and you've implemented the dealloc method, it will be called.


So, for example, lets say that you want to create two arrays of numbers and put them into a dictionary using strings as the keys.

NSArray *firstArray = [NSArray arrayWithObjects:
	[NSNumber numberWithInt: 1],
	[NSNumber numberWithInt: 2],
	[NSNumber numberWithInt: 3],
	nil];
NSArray *secondArray = [NSArray arrayWithObjects:
	[NSNumber numberWithInt: 4],
	[NSNumber numberWithInt: 5],
	[NSNumber numberWithInt: 6],
	nil];
NSDictionary *myDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
	firstArray, 		@"FirstArrayKey",
	secondArray, 	@"SecondArrayKey",
	nil, 			nil];

When you create firstArray, it begins with a retainCount of 1, but it's in the autorelease pool, which means that as soon as the code that's currently executing is finished, it will be released, its retainCount will drop to zero, and it will be deallocated. The same applies for secondArray. Factory methods (like +[NSArray arrayWithObjects:] ) generally work this way. Internally, the factory method is doing something like this:
+ (id)arrayWithObjects: (...)args
{ return [[[self class] alloc] initWithObjects: args] autorelease]; }


But when you insert the arrays into myDictionary, they are both retained, making their retainCounts both 2. The newly created dictionary has a retainCount of 1, and is in the autorelease pool, so when the currently executing code is finished, it will be released, dropping its retainCount to zero, meaning it will be deallocated. When it's deallocated, all of the items in the dictionary are released as well, so each array's retainCount drops to zero, and they're both deallocated.

So, if you wanted to keep the dictionary valid beyond just the currently executing code, you'd have to retain it. Doing that would make its retainCount 2. When the currently executing code finishes, the dictionary would be released, dropping its retainCount to 1 (because the dictionary is in the autorelease pool). But since its retainCount is still above zero, it's not deallocated, and nothing changes in the array's retain counts. So everything is fine.

Of course, if you retain the dictionary, you need to release it somewhere, or it will leak.

Here's the basic rule of thumb for memory management:
Every call to "alloc", "retain", "copy" or "mutableCopy" must have exactly one corresponding code path that will call "release" or "autorelease". Less will leak memory. More will double-release objects.


I was sort of imprecise when I mentioned the "currently executing code". What I mean is the current runloop. Your application sits idle until some event occurs, at which point your code begins to "do stuff". An autorelease pool is created, and is valid as long as your code is "doing stuff". When your code is done "doing stuff", everything in the autorelease pool gets released, and your application goes back to waiting for a new event to occur.

Clear as mud?

Jason


On Feb 3, 2005, at 6:47 PM, Richard Patterson wrote:

Is there sample code somewhere for how to load entries into an NSMutableDictionary? My initial effort seems to have created something crash inducing. I think my mistake is that I assumed the objects were being copied when they were put into the dictionary.

Does a dictionary only contain a references to an objects that must be globaly available along with the dictionary?

Should I create an array of objects and then use that to load the dictionary?

Richard Patterson
Illusion Arts
6700 Valjean Avenue
Van Nuys, CA 91406
818 901-1077
FAX: 818 901-1995
email@hidden

_______________________________________________
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



_______________________________________________ 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
References: 
 >Loading a Dictionary (From: Richard Patterson <email@hidden>)

  • Prev by Date: Loading a Dictionary
  • Next by Date: Re: Loading a Dictionary
  • Previous by thread: Loading a Dictionary
  • Next by thread: Re: Loading a Dictionary
  • Index(es):
    • Date
    • Thread