2015-02-12 1 views
0

В моем приложении iOS я использую Core Data для выполнения выборки и удаления очень большого набора данных. Этот процесс занимает приблизительно 5-10 секунд. Я бы хотел сделать откаты, если пользователь решит выключить устройство до завершения процесса. Тем не менее, проблема заключается в том, чтобы ИСПЫТЫЙ экземпляр NSManagedObjectContext вызывал функцию отката из соответствующего метода AppDelegate. В моем приложении, я называю мои методы Ядро данных с помощью объекта Singleton, как это:Нужно получить доступ к тому же экземпляру ManagedObjectContext при выполнении функций отката из AppDelegate в базовых данных

static MySingleton *sharedSingleton = nil; 


+ (MySingleton *) sharedInstance { 

    if (sharedSingleton == nil) { 
     sharedSingleton = [[super alloc] init]; 
    } 
    return sharedSingleton; 
} 

В моем приложении я вернуть экземпляр из NSManagedObjectContext так:

- (NSManagedObjectContext *) managedObjectContext{ 

    if (_managedObjectContext != nil) { 
     return _managedObjectContext; 
    } 
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 

    if (coordinator != nil) { 

     _managedObjectContext = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSMainQueueConcurrencyType]; 
     [_managedObjectContext setPersistentStoreCoordinator:coordinator]; 

     //Undo Support 
     NSUndoManager *anUndoManager = [[NSUndoManager alloc] init]; 
     [self.managedObjectContext setUndoManager:anUndoManager]; 
    } 
    return _managedObjectContext; 
} 

Я тогда называть, и назначить его в качестве ссылки, как это:

NSManagedObjectContext *context = [[MySingleton sharedInstance] managedObjectContext]; 

Как бы я сделать этот экземпляр ManagedObjectContext доступный мне для использования в AppDelegate, так что я могу перекличку назад функция?

Заранее благодарим всех, кто отвечает.

ответ

2

Во-первых, тем лучше (безопаснее) способ создания Синглтон, как в приведенном примере здесь: Create singleton using GCD's dispatch_once in Objective C, а именно:

+ (instancetype)sharedInstance 
{ 
    static dispatch_once_t once; 
    static id sharedInstance; 
    dispatch_once(&once, ^{ 
     sharedInstance = [[self alloc] init]; 
    }); 
    return sharedInstance; 
} 

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

Если вы находитесь в центре отладки и задаете некоторые фундаментальные предположения о своем коде, дайте контексту управляемого объекта имя (или зарегистрируйте адрес памяти указателя MOC), который вы можете проверить позже в отладчике , чтобы убедиться, что вы имеете дело с одним и тем же.

Обратите внимание также, что если вы создали выделенный контекст управляемого объекта только для такого импорта, вам не нужно откатывать его обратно. Вы можете просто отказаться от него.

В моих приложениях у меня обычно есть контекст управляемого объекта (родительский) и несколько дочерних контекстов; один ребенок для основного потока, другой - для операций типа импорта.

1

В качестве альтернативного решения вместо отката изменений вы можете создать сценарий с несколькими контекстами, в котором дочерний управляемый объектный контекст добавит все необходимые вам данные, и в конце концов, когда это будет сделано, вы сохраните дочерний контекст, отправляющий новые данные к основному управляемому объекту. Таким образом, основной контекст управляемого объекта не влияет на весь процесс.

Это отличная статья в качестве ссылки Multi-Context CoreData.

В основном то, что вам нужно сделать, это

// create main MOC 
_mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
[_mainContext setPersistentStoreCoordinator:_persistentStoreCoordinator]; 

// create child MOC 
_childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
_childContext.parentContext = _mainContext; 

Надеется, что это помогает.