托管对象上下文未正确传递,数组始终为零

时间:2015-11-25 20:22:22

标签: ios objective-c nsmanagedobjectcontext nsfetchrequest

我试图将我的进程移动到后台线程,但我相信没有正确传递managedObjectContext。在位置管理器的后台队列中初始化它,如下所示:

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类中一切正常,直到我尝试获取。该数组始终为null。我想我没有正确传递我的managedObjectContext。我曾尝试使用self.managedObjectContext,但代码崩溃或者,数组仍为null。 self.managedObjectContext和简单的managedObjectContext之间有什么区别。我还读过一些严格禁止将一个托管对象从一个MOC传递到另一个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];

1 个答案:

答案 0 :(得分:0)

核心数据允许两种不同的并发模型:不推荐使用的线程限制和队列限制。使用初始化程序NSManagedObjectContext创建initWithConcurrencyType:时,它会使用队列限制。

队列限制要求应用程序遵循一组简单的规则。必须通过performBlock:performBlockAndWait:方法访问上下文及其对象的任何非线程安全方法或属性。唯一安全的方法是上下文的只读访问器和上下文的属性设置器。必须通过这些方法访问NSManagedObject上下文及其拥有的NSManagedObject的所有其他方法。

在您的情况下,您执行的提取必须在传递给其中一种方法的块中完成。例如:

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

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

开发时,一个好主意是启用Core Data并发调试断言来捕获这些和其他问题。当传递应用程序时,启动Core Data上的com.apple.CoreData.ConcurrencyDebug参数将在执行并发问题时停止执行,例如违反上述规则。这有助于在开发周期的早期发现问题。