Reputation: 99
I have a pretty simple question. While I am fairly new to Objective-C, I have gotten pretty comfortable with the language and the memory management model.
I understand ownership pretty well and the notion of explicit and implicit. I also understand that when you add anything to a collection, it takes ownership of the keys and values and releases that ownership on release.
My question relates to the releasing of a collection of collections (aka a Bag). I have the following code:
// levelDict is a member NSMutableDictionary on the Class
BOOL newDict = NO;
BOOL newArray = NO;
NSNumber *levelKey = [NSNumber numberWithInt:toLevel];
NSMutableDictionary *dict = [levelDict objectForKey:levelKey];
if ( dict == nil ) {
dict = [[NSMutableDictionary alloc] init];
[levelDict setObject:dict forKey:levelKey];
newDict = YES;
}
// Now look for the array...
NSNumber *typeKey = [NSNumber numberWithInt:objectType];
NSMutableArray *array = [dict objectForKey:typeKey];
if ( array == nil ) {
array = [[NSMutableArray alloc] init];
[dict setObject:array forKey:typeKey];
newArray = YES;
}
// Now add the object to the array...
[array addObject:object];
// Deal with our memory management
if ( newArray ) {
[array release];
}
if ( newDict ) {
[dict release];
}
This code creates a Map where each entry then contains an Array (aka Bag). If I release the dictionary object levelDict which owns the array of objects for each entry, I am assuming that release will cascade through the arrays as well? Or do I have to iterate over the dictionary and explicitly release each of the arrays?
Now for the extra credit question - why am I doing this versus defining a single object of collections? Well, in other languages like Java, Object instantiation can get very expensive. I am assuming this is the case with Objective-C. Maps of associative arrays are very efficient.
Thanks Bryan
Upvotes: 1
Views: 1033
Reputation: 45581
Code is simpler using autoreleased dict/array since the branching doesn't affect the retain count.
// levelDict is a member NSMutableDictionary on the Class
NSNumber *levelKey = [NSNumber numberWithInt:toLevel];
NSMutableDictionary *dict = [levelDict objectForKey:levelKey];
if ( dict == nil ) {
dict = [NSMutableDictionary dictionary];
[levelDict setObject:dict forKey:levelKey];
}
// Now look for the array...
NSNumber *typeKey = [NSNumber numberWithInt:objectType];
NSMutableArray *array = [dict objectForKey:typeKey];
if ( array == nil ) {
array = [NSMutableArray array];
[dict setObject:array forKey:typeKey];
}
// Now add the object to the array...
[array addObject:object];
Upvotes: 0
Reputation: 243156
From the Collections programming guide: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Collections/Articles/Arrays.html
"And when you add an object to an Objective-C array, the object isn’t copied, but rather receives a retain message before its id is added to the array. When an array is deallocated, each element is sent a release message."
Dictionaries and Sets behave the same way.
Upvotes: 1
Reputation: 35935
As long as the NSDictionary
is the only container retaining a reference to a given NSObject
(NSArray
included), it will get deallocated when the NSDictionary
does.
Upvotes: 0
Reputation: 171864
When a dictionary is released, all keys and values are released. If they are arrays, releasing them will also release all entries in the array, and so on.
Of course, adding anything to a dictionary will retain the keys and values, and adding anything to a mutable array will retain the entries.
Pretty straightforward...
Upvotes: 3