Понимание переменных в блоках (директива __block) - PullRequest
0 голосов
/ 15 марта 2012

У меня есть простая функция внутри категории NSManagedObjectContext, чтобы помочь мне получить результаты от моего moc.Я выполняю результаты внутри блока executeBlockAndWait, предоставленного из экземпляра moc.Мне нужно вернуть автоматически освобожденный массив, и обычно executeFetch из moc уже делает это.Но в этом случае мне нужно сохранить массив внутри блока, хотя я объявляю массив с помощью директивы __block.Похоже, что он освобождается после завершения блока.Это нормально?Спасибо.

-(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];

}

1 Ответ

3 голосов
/ 15 марта 2012

Я подозреваю, что performBlockAndWait имеет внутреннее выполнение пуска автоматического освобождения пула. Таким образом, массив, возвращаемый executeFetchRequest:error:, освобождается при выходе из блока, поэтому вам необходимо сохранить его.

Обратите внимание, что это не будет проблемой при ARC; указатель array автоматически сохранит массив. Если у вас есть возможность, я бы рекомендовал перейти на ARC. А пока, теперь вы знаете, что происходит.

...