I have a simple function inside a NSManagedObjectContext category to help me get results from my moc. I’m executing the results inside the performBlockAndWait block supplied from the moc instance. I need to return an autoreleased array, and normally the executeFetch from the moc already does that. But in this case I need to retain the array inside the block even though I declare the array with the __block directive. It looks like it gets released once the block is finished.
Is this normal?
Thank you.
-(NSArray*)executeFetchWithEntityName:(NSString*)entityName predicate:(NSPredicate*)predicate{
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:self];
if (!entity) {
NSLog(@"entity is nil in executeFetchWithEntityName: %@", entityName);
return [[[NSArray alloc]init]autorelease];
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
[fetchRequest setEntity:entity];
if(predicate){
[fetchRequest setPredicate:predicate];
}
__block NSError *error = nil;
__block NSArray *array = nil;
[self performBlockAndWait:^{
array = [self executeFetchRequest:fetchRequest error:&error];
[array retain]; <------ IF I DONT RETAIN HERE, IT CRASHES FURTHER ON
}];
NSLog(@"retain count: %i", array.retainCount);
if (error) {
NSLog(@"error");
array = nil;
}
[fetchRequest release];
return [array autorelease];
}
I suspect that
performBlockAndWaithas an internal autorelease pool wrapping execution of the block. As such, the array returned byexecuteFetchRequest:error:is released when you leave the block, which is why you need to retain it.Note that this wouldn’t be an issue under ARC; the
arraypointer would retain the array automatically. If you’ve got the option, I’d recommend switching to ARC. But in the meantime, now you know what’s going on.