2017-08-01 23 views
0

NSSortDescriptorを使用してさまざまな属性でソートを実行した後、ソート順をキャプチャしてコアデータに戻したいと思います。 uXを安定して保つために、別のMOCを使用してバックグラウンドでこれを実行しようとしています。しかし、おそらくいくつかの他のことが起こっているので、列挙されたエラーの間に突然変異が起こっています。サーバーとの同期やフェッチを行うFRCなどです。IOS/Objective-C:バックグラウンドでNSFe​​tchedResultsControllerの後にコアデータに保存

誰かが自分のコードで何が間違っているのを見ることができますか?事前に感謝の意を表します。

-(NSFetchedResultsController *)fetchedResultsController { 

//code to carry out fetch 
//Sort order specified according to parameters 

_theItems =[_fetchedResultsController fetchedObjects]; 
//at this point fetch should be complete 
NSManagedObjectContext *mainMOC = _managedObjectContext; 
    NSManagedObjectContext*privateContext =[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    [privateContext setParentContext:mainMOC]; 
    [privateContext performBlock:^{ 

     for (int i = 0; i < _theItems.count; i++) 
     { 
      Items* oneitem = theItems[i]; 
      oneitem.sortorder = i; 
     } 

     NSError *error = nil; 
     if (![privateContext save:&error]) { 
      NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]); 
      abort(); 
     } 
     [mainMOC performBlockAndWait:^{ 
      NSError *error = nil; 
      if (![mainMOC save:&error]) { 
       NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]); 
       //abort(); 
      } 
      else { 
       _managedObjectContext = mainMOC; 
      } 
     }]; 
    }]; 
    mainMOC=nil; 
    privateContext = nil; 

return _fectchedResultsController; 
} 

編集:アップルのドキュメントから

NSArray *jsonArray = …; //JSON data to be imported into Core Data 
NSManagedObjectContext *moc = …; //Our primary context on the main queue 

NSManagedObjectContext *private = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
[private setParentContext:moc]; 

[private performBlock:^{ 
    for (NSDictionary *jsonObject in jsonArray) { 
     NSManagedObject *mo = …; //Managed object that matches the incoming JSON structure 
     //update MO with data from the dictionary 
    } 
    NSError *error = nil; 
    if (![private save:&error]) { 
     NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]); 
     abort(); 
    } 
    [moc performBlockAndWait:^{ 
     NSError *error = nil; 
     if (![moc save:&error]) { 
      NSLog(@"Error saving context: %@\n%@", [error localizedDescription], [error userInfo]); 
      abort(); 
     } 
    }]; 
}]; 

編集2:viewdidappear内のコードを配置

は例外を停止しました。さらに、私はコードをフォローするように変更しました。これは動作するように見えます。今はスレッドセーフですか?

for (int i = 0; i < _theItems.count; i++) 
      { 
      Items* oneitem = theItems[i]; 
      NSManagedObjectID* oneID = oneitem.objectID; 
      Items *myItem = [privateContext objectWithID:oneID]; 
      myItem.sortorder = i; 

      } 
+1

私は何かが非常に間違っているのではないかと恐れています。プライベートコンテキストを設定して、一連のオブジェクト(おそらくManagedObjectのサブクラス)を反復処理しているようですが、どこから来たのでしょうか?そのメソッドのバリアントのいずれかでobjectWithIDを使用しているオブジェクトを取得していないので、主コンテキストから取得したオブジェクトを操作している可能性があります(performBlock呼び出し内でこれを行うため、その後、間違ったスレッド上の別のコンテキストからオブジェクトを操作した場合、プライベートコンテキストを保存してみると、それはすべてうまくいくと思います。いいえ。 – TheBasicMind

+0

私はまた、マネージオブジェクトはスレッドセーフではありませんが、オブジェクトIDはobjectwithIDを使用してすべてのマネージオブジェクトを取得する必要があることを読んでいます。しかし、私はまた、NSPrivateQueueConcurrencyTypeがこのプロセスを簡略化したように見えることを読んだので、上記を行うことができます。多分私は間違った思いをするでしょう。参照を検索しようとします。 – user6631314

+0

これは私がドキュメントで読んだものです:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/Concurrency.html – user6631314

答えて

0

複数のコンテキストからNSManagedObjectにアクセスすることはできません。 [NSFetchedResultsController fetchedObjects]_managedObjectContextが所有するオブジェクトを返すと仮定すると、privateContextからそれらのオブジェクトにアクセスすることはできません。

NSManagedObjectIDをプライベートMOCに渡し、そのIDを使用して、対応するオブジェクトのメインMOCを照会することがあります。

それは意味がありますか?

+0

でオブジェクトを取得する必要があります。FRCで自動的に管理されるオブジェクトのフェッチされたオブジェクトですか? – user6631314

+0

はい。 [documentation](https://developer.apple.com/documentation/coredata/nsfetchedresultscontroller/1622278-fetchedobjects?language=objc)から:_ "結果配列は、コントローラの管理対象オブジェクト内の管理対象オブジェクトのメモリ内状態を反映しますコンテキスト "_ – kevdoran

+0

viewdidloadにコードを移動するとエラーが表示されなくなりました。私は実際には、FRC、NSArray * theItems、またはこの場合は_theItemsからの一時的な注文が必要です。あなたはobjectforidを使用するコードを提案できますか?配列から各sortOrderを取得すると、ループに入ると思います。 – user6631314

関連する問題