2015-11-25 12 views
0

Я пытаюсь переместить мой процесс в фоновый поток, но я считаю, что управляемый объектОбъект не передается правильно. Инициализировать его в фоновом режиме очереди менеджера местоположения, а так:Контекст управляемого объекта не передается корректно, массив всегда равен нулю

managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    self.managedObjectContext.parentContext = moc; 
    locationManager = [[CLLocationManager alloc] init]; 
    self.locationManager.delegate = self; 
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]){ 
     [self.locationManager requestAlwaysAuthorization]; 
    } 
    geoCoder = [[CLGeocoder alloc] init]; 



    NSNumber *nsInterval = [[NSUserDefaults standardUserDefaults] objectForKey:@"location_interval"]; 
    interval = (nsInterval == nil) ? -1 : [nsInterval intValue]; 

bgBackupHandler = [[BackgroundBackupHandler alloc]init]; 
bgBackupHandler.managedObjectContext = self.managedObjectContext;   

Я затем вызвать его в другом методе в месте класса обработчика, как так:

[bgBackupHandler OnSyncComplete:[NSNumber numberWithInt:0] message:@"BG-Backup Called"]; 

Тогда в классе все работает bgBackupHandler пока я не попытаюсь извлечь. Массив всегда равен нулю. Я думаю, что я не передал свой managedObjectContext правильно. Ive пытался использовать self.managedObjectContext, но код либо сбой, либо массив по-прежнему равен нулю. В чем разница между self.managedObjectContext и просто managedObjectContext. Я также читал некоторые, где строго запрещено передавать управляемый объект из одного MOC в другой.

Работа выполнена в фоновом режиме.

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"bdir_0001" inManagedObjectContext:managedObjectContext]; 
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
    [request setEntity:entityDescription]; 
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@", strDirName]; 
    [request setPredicate:predicate]; 
    NSError *error = nil; 

    NSArray *array = [managedObjectContext executeFetchRequest:request error:&error]; 
+0

Ваш класс 'BackgroundBackupHandler' имеет свойство' managedObjectContext', и все же, когда вы делаете запрос, вы используете 'managedObjectContext' самостоятельно, не ссылаясь на свойство. Где эта переменная определена? – Avi

+0

Выполняется ли выборка в фоновом режиме, заключенном в 'executeBlock:'? – quellish

+0

@avi переменная является свойством в интерфейсе и синтезируется в разделе реализации. – 3rdeye7

ответ

0

Основные данные позволяют использовать две различные модели параллелизма: ограничение по контенту, которое устарело и ограничено в очереди. Когда создается NSManagedObjectContext с инициализатором initWithConcurrencyType:, он использует ограничение в очереди.

Ограничение в очереди требует, чтобы приложение выполняло ряд простых правил. Доступ к любым небезопасным методам или свойствам контекста и его объектам должен выполняться с помощью методов performBlock: или performBlockAndWait:. Единственными безопасными методами являются доступные для чтения аксессоры контекста и средства настройки контекста. Все остальные методы контекста NSManagedObject и NSManagedObject, с которыми он владеет, должны быть доступны с помощью этих методов.

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

[managedObjectContext performBlock:^{ 
    NSError *error = nil; 
    NSArray *array = nil; 

    array = [managedObjectContext executeFetchRequest:request error:&error]; 
}]; 

Это хорошая идея при разработке для того, чтобы ядро ​​данных утверждений отладки параллелизма, чтобы поймать эти и другие вопросы. Когда приложение передается, аргумент com.apple.CoreData.ConcurrencyDebug при запуске Core Data приостанавливает выполнение, когда он сталкивается с проблемой параллелизма, как нарушение правил, описанных выше. Это помогает уловить проблемы в начале цикла разработки.