0

我需要从后台线程更改一些实体,所以我执行以下操作:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSManagedObjectContext *parent = [Default managedObjectContext];
    NSManagedObjectContext *editContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:parent.concurrencyType];
    [editContext setPersistentStoreCoordinator:[Default persistentStoreCoordinator]];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(saveChanges:)
                                                 name:NSManagedObjectContextDidSaveNotification
                                               object:editContext];

    NSFetchRequest *request = [NSFetchRequest new];
    ...
    NSArray *fetchedObjects = [context executeFetchRequest:request error:nil];

    NSError *error;
    [editContext save:&error]
});

它正在工作,但有时它会停止工作,只是退出 executeFetchRequest:request 上的函数。它发生在模拟器上。那么从后台线程更改数据是正确的方法吗?

4

1 回答 1

1

是的,您可以将后台线程中的数据更改为核心数据,但作为黄金法则,“每个线程都应该有自己的 NSManagedObjectContext 实例”和相同的 persistentStoreCoordinator,因为这样可以避免数据库死锁和其他讨厌的问题。

但是我在你的代码中看到了一些问题,我不知道是编辑错误还是真正的错误。

  1. context未使用您用于获取请求的内容。
  2. 您应该在执行完之后移除saveChanges观察者save。(您不想被其他更改通知)
  3. 在块中使用self是一种不好的做法(不是你的情况),因为它可能导致保留周期。你应该使用__block YoirClass *blocksafeSelf = self;

此外,如果没有错误,也很难知道这里的问题可能是什么,因此您应该将错误参数传递给fetchRequest并检查是否有错误。

还要确保它真的退出了函数,因为在死锁的情况下,它看起来正在退出,但实际上它只是在排队等候。

于 2013-05-16T19:20:56.550 回答