1

当我在 2 个屏幕之间切换几次时,我的 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,所以它让每个线程都有一个新线程。但是现在当我在 2 个屏幕之间切换几次时,它会冻结在 [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];
}
4

1 回答 1

2

Core Data 通常不是线程安全的。经验法则是为NSManagedObjectContext每个线程创建一个。我相信您正在线程之间重用您的上下文,这就是导致问题的原因。

核心数据并发文档:

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

于 2012-05-02T14:18:00.333 回答