2

Как вернуть новый объект, сохраненный в coredata, если я использую performBlock, чтобы сохранить управляемый объектObjectContext?Coredata performBlock затем возвращает новое значение

Требование: добавить запись в coredata и вернуть ее. Мой код выглядит примерно так:

//create a privateMOC 
NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 

//set parentContext 
[private setParentContext:self.coredataManager.managedObjectContext]; 

__block Detail *object = nil; 

[private performBlock:^{ 
    //fetch from the db 
    object = [self.coredataManager insertObjectWithEntityName:NSStringFromClass([Detail class])]; 

    //save the private context 
    NSError *error = nil; 
    if (![private save:&error]) { 
     NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]); 
    } 

}]; 

return object; 

Здесь, поскольку экономия происходит в блоке, сначала выполняется возврат. Но мне нужен object с последним значением. Любое предложение пожалуйста.

+0

Вы не хотите использовать 'performBlockAndWait'. Это приводит к блокировке вызывающего потока и может вызвать проблемы с блокировкой, если это не сделано тщательно. В общем, вам следует избегать 'performBlockAndWait', если нет другого решения. Я нашел это очень редко. Кроме того, вы ничего не можете сделать с объектом, который вы возвращаете за пределы другого 'executeBlock', за исключением, может быть, спрятать его где-нибудь для последующей ссылки. Итак, зачем вообще его возвращать? Почему бы не сделать то, что вы собираетесь делать с ним внутри 'performBlock'? –

+0

Новое созданное значение передается нескольким местам, включая фоновые приложения/процесс. –

+0

@JodyHagins: Plz посмотреть мой комментарий –

ответ

1

Я сделал некоторые исследования и обнаружил, что не было слишком трудно решить эту проблему:

я заменил performBlock с performBlockAndWait и он работал.

Причина проста: performBlock является асинхронным, в то время как performBlockAndWait синхронно.

+0

Просто помните, что он блокирует и что вы возвращаете его, связанный с временным контекстом, поэтому вам нужно позаботиться только о том, чтобы получить доступ к нему в этом контексте (который, как правило, никто не смотрит на собственные ...) – Wain

2

Вместо возвращает вновь созданный объект Core Data, передайте метод конструктора блоку с параметром типа создаваемого объекта.

Когда объект был создан в блоке performBlock: объекта управляемого объекта, вызовите ваш блок completion и передайте вновь построенный объект Core Data.

+ (void)coreDataObjectWithJSON:(NSDictionary *)json completion:(void (^)(NSYourCoreDataObject *coreDataObject))completion { 

    [yourManagedObjectContext performBlock:^{ 

     NSEntityDescription *entity = [NSEntityDescription entityForName:... inManagedObjectContext:...]; 

     NSYourCoreDataObject *coreDataObject = [[NSYourCoreDataObject alloc] initWithEntity:entity insertIntoManagedObjectContext:...]; 

     if (completion) { 
      // "return" the new managed object 
      completion(coreDataObject); 
     } 
    }]; 
} 
Смежные вопросы