我的iOS应用程序依赖多线程保存

时间:2012-05-02 14:01:04

标签: ios multithreading core-data objective-c-blocks

当我在两个屏幕之间进行两次扫描时,我的iOS应用程序会依赖于野蛮。 它属于存储数据,但只是冻结没有错误。 有人知道如何解决这个问题吗?

self.fetchF = dispatch_queue_create(label, NULL);
dispatch_async(self.fetchF, ^{

    NSArray *feeds = [FeedFetcher getData:self.pageTitle downloadBy:@"up"];

    NSManagedObjectContext *newContext = self.managedObject;

    for (NSDictionary *feedInfo in feeds) {
        [Feed FeedWithInfo:feedInfo InManageObject:newContext];
    }

    dispatch_async(dispatch_get_main_queue(), ^{

        NSError *error = nil;
        if (newContext != self.managedObject)
            [newContext save:&error];

        if (error)
            NSLog(@"Error save : %@", error);

        [self setupFetchedResultsController];

        [self downloadImages:feeds];
    });        
});

编辑:

我更改了我的managedobjectcontext,因此每个线程都有一个新线程。 但现在,当我在两个屏幕之间进行两次屏蔽时,会冻结[self.fetchedResultsController performFetch:& error];没有错误.. 有人想出一个解决方案吗?

- (void)performFetch
{
    if (self.fetchedResultsController) {
        if (self.fetchedResultsController.fetchRequest.predicate) {
            if (self.debug) NSLog(@"[%@ %@] fetching %@ with predicate: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName, self.fetchedResultsController.fetchRequest.predicate);
        } else {
            if (self.debug) NSLog(@"[%@ %@] fetching all %@ (i.e., no predicate)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName);
        }
        NSError *error;
        if (self.fetchedResultsController != nil)
            [self.fetchedResultsController performFetch:&error];

        if (error) NSLog(@"[%@ %@] %@ (%@)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), [error localizedDescription], [error localizedFailureReason]);
    } else {
        if (self.debug) NSLog(@"[%@ %@] no NSFetchedResultsController (yet?)", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
    }
    [self.tableView reloadData];
}

1 个答案:

答案 0 :(得分:2)

核心数据通常不是线程安全的。经验法则是为每个线程创建一个NSManagedObjectContext。我相信你在线程之间重复使用你的上下文,这导致了问题。

核心数据并发文档:

  

核心数据使用线程(或序列化队列)限制来保护   托管对象和托管对象上下文(请参阅“与...并发”   核心数据“)。这样做的结果是上下文假设了   默认所有者是分配它的线程或队列 - 这是   由调用其init方法的线程确定。你不应该,   因此,在一个线程上初始化一个上下文然后将其传递给一个   不同的线程。相反,您应该传递对持久性的引用   存储协调器并使接收线程/队列创建一个新的   从中得到的背景。如果您使用NSOperation,则必须创建   main中的上下文(用于串行队列)或start(用于并发)   队列)。