When to release NSMutableArray from loop in viewDidLoad?
I've got the following lines in my viewDidLoad:
self.开发者_运维问答sections = [[NSMutableDictionary alloc] init];
BOOL found;
// Loop through the signs and create our keys
for (NSDictionary *sign in self.allSigns)
{
NSString *c = [[sign objectForKey:@"name"] substringToIndex:1];
found = NO;
for (NSString *str in [self.sections allKeys])
{
if ([str isEqualToString:c])
{
found = YES;
}
}
// If string is not found, add it in uppercase to the sections array.
if (!found)
{ ** Potential leak of an object.**
[self.sections setValue:[[NSMutableArray alloc] init] forKey:[c uppercaseString]];
}
[sign release];
}
// Loop again and sort the signs into their respective keys
for (NSDictionary *sign in self.allSigns)
{
NSString *dummy = [[sign objectForKey:@"name"] substringToIndex:1];
[[self.sections objectForKey:[dummy uppercaseString]] addObject:sign];
}
// Sort each section array
for (NSString *key in [self.sections allKeys])
{
[[self.sections objectForKey:key] sortUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]]];
}
//self.numberOfEntries = [[allSigns allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
[dataLoader release];
[super viewDidLoad];
Afterwards I use the self.sections array in various tableview delegate methods. It is also properly declared in my header and (of course) synthesized.
But when I run Build & Analyse, Xcode tells me there's a potential leak of an object. But I'm not sure where I should release this NSMutableArray because I don't know, for instance, the name of the object.
Should I put it in my dealloc or release it after the loop?
With regards,
Rutger
Never pass alloc-init'd objects directly into an NSDictionary
:
[self.sections setValue:[[NSMutableArray alloc] init] forKey:[c uppercaseString]];
Pass an autoreleased empty array instead:
[self.sections setValue:[NSMutableArray array] forKey:[c uppercaseString]];
The sections dictionary is going to retain it, so you can release it right there, like:
NSMutableArray* newArray = [[NSMutableArray alloc] init];
[self.sections setValue:[newArray forKey:[c uppercaseString]];
[newArray release];
BoltClock and zpasternack have provided two correct answers to your question, but I have a couple of tips to improve other areas of your code.
If the dictionary does not include a key, objectForKey will return nil. You can use this to speed up your checking for keys.
found = ([self.sections objectForKey:c] != nil);
You can also move the adding of objects into the first loop and remove the second loop.
if(!found) {
//add new mutable array
}
[[self.sections objectForKey:c] addObject:sign];
Is there a reason you are releasing sign in the first loop? You did not allocate it here, you just got it from the array.
NSDictionary uses fast enumeration over the keys automatically, so you can replace for(NSString *key in [self.sections allKeys])
with for(NSString *key in self.sections)
.
精彩评论