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スレッドごとに作成することです。スレッド間でコンテキストを再利用しているため、問題が発生していると思います。

コア データの同時実行に関するドキュメント:

コア データは、スレッド (またはシリアル化されたキュー) 制限を使用して、管理対象オブジェクトと管理対象オブジェクト コンテキストを保護します (「コア データとの同時実行」を参照)。この結果、コンテキストは、デフォルトの所有者がそれを割り当てたスレッドまたはキューであると想定します。これは、その init メソッドを呼び出すスレッドによって決定されます。したがって、あるスレッドでコンテキストを初期化してから、それを別のスレッドに渡すべきではありません。代わりに、永続ストア コーディネーターへの参照を渡し、受信スレッド/キューにそこから派生した新しいコンテキストを作成させる必要があります。NSOperation を使用する場合は、main (シリアル キューの場合) または start (同時キューの場合) にコンテキストを作成する必要があります。

于 2012-05-02T14:18:00.333 に答える