2013-02-20 1 views
1

Я хочу, чтобы моя основная нить никогда не блокировалась, поэтому я хочу, чтобы мои основные данные сохранялись в фоновом режиме.iOS background save in Core Data

Я читал документы Apple вместе с этой ссылкой (и многие другие, но я нашел это очень полезным): http://www.cocoanetics.com/2012/07/multi-context-coredata/, хотя я не могу получить архитектуру правильно.

В моей AppDelegate.m:

- (NSManagedObjectContext *)managedObjectContext 
{ 
    if (_managedObjectContext != nil) { 
     return _managedObjectContext; 
    } 

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
    if (coordinator != nil) { 
     _saveContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
     [_saveContext setPersistentStoreCoordinator:coordinator]; 

     _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
     [_managedObjectContext setParentContext:_saveContext]; 
    } 
    return _managedObjectContext; 
} 

Тогда, чтобы спасти, я хотел бы сделать что-то вроде этого:

// var 'context' is the context coming from method managedObjectContext 
// this code is in the same thread 'context' is created in (the main thread) 
NSError *error = nil; 
if ([context save:&error]) { 
    [context.parentContext performBlock:^{ 
     NSError *err = nil; 
     if(![context.parentContext save:&err]) { 
      NSLog(@"Error while saving context to the persistent store"); 
     } 
    }]; 
} else { 
    // handle error 
} 

Это то, что я хотел бы получить от чтения ссылку я поставляемого ранее. Сохранение не работает, как только приложение закрыто и снова открыто, изменения, внесенные в любые управляемые объекты, исчезли: они никогда не сохранялись в сохраненном хранилище.

Имеет смысл, я думаю, с тех пор как я создал 2 NSManagedObjectContexts в 1 потоке, Apple docs четко заявляет, что имеет только 1 NSManagedObjectContext для потока. Итак, как настроить родительское/дочернее отношение между _managedObjectContext и _saveContext? Я знаю, что _saveContext необходимо инициализировать в другом потоке, но я не могу заставить этот подход работать.

+0

Родительский контекст создает свой собственный поток, вам не нужно его создавать. Ваш код выглядит нормально, я не вижу очевидной ошибки. Вы проверили, действительно ли выполняется операция внутреннего сохранения? Вы также можете активировать отладку Core Data SQLite, установив параметр запуска '-com.apple.CoreData.SQLDebug 1', после чего вы должны увидеть, что что-то сохранено или нет. –

+0

Я не знал наверняка, что контекст создал свой собственный поток, предполагая, что я запутался со всеми сообщениями, которые я нашел, написанными до iOS 5. Ошибка заключалась в том, что я прошел через неправильный контекст в какой-то момент своего кода (у меня есть другой фоновые очереди, а также для извлечения), а внутреннее сохранение - это не сохранение корневого контекста. Получил, что все это разобралось сейчас в моей голове (и коде), спасибо! ps: можете ли вы опубликовать это как ответ, чтобы я мог его принять? – mmvie

ответ

0

(Из комментариев)

Все «новые» управляемый объект типы контекстов (NSMainQueueConcurrencyType, NSPrivateQueueConcurrencyType) управлять своими нитями, не нужно, чтобы создать контекст на специальной теме. Единственное, что нужно помнить, - всегда использовать performBlock или performBlockAndWait для операций в контексте. Это гарантирует, что операции выполняются в правой очереди и потоке.

Так что ваш код в порядке.

(Как выяснилось, ошибка в том, что неправильный контекст был передан в вашей обычной экономии и поэтому внутренняя экономия не было сделано в контексте верхнего уровня.)