2016-07-12 8 views
0

現在、私はマルチスレッド環境で使用されている新しいCoreDataアーキテクチャを検証中です。解析のために、私はGDCoreDataConcurrencyDebuggingを使用しています。これは、ManagedObjectが間違ったスレッド/キューからアクセスされるたびに(私が理解する限り)警告を出力します。CoreData並行性と解放オブジェクト

は今、私はこのような警告のトンを取得しています:

Invalid concurrent access to managed object calling 'release'

私は警告が生成されたブレークポイントを置くことができたとのコードは次のようになります。

-(MyObject*) createMyObject { 
    return (MyObject*)[self insertNewObjectEntityWithName:@"MyObject"]; 
} 

-(NSManagedObject*) insertNewObjectEntityWithName:(NSString*) entityName { 
    __block NSManagedObject *managedObject; 
    [self.managedObjectContext performBlockAndWait:^(void) { 
     managedObject = [NSEntityDescription insertNewObjectForEntityForName:entityName 
             inManagedObjectContext:self.managedObjectContext]; 
    }]; 
    return managedObject; 
} 

その復帰後のcreateMyObjectメソッドの破損は、オブジェクトがリリースされたときのことです。 CoreDataの同時実行とオブジェクトリリースで見逃したことはありますか? 私は周りを見回して、オブジェクトリリースに関して何も言及されていません、私が使用していないオートリースプールについてのみです。

答えて

2

performBlockAndWait:コールで作業を実行していますが正しいです。しかし、おそらく別のスレッドからオブジェクトを返します。それは合法ではありません。常に有効なobjectIDプロパティを除いて、すべての管理対象オブジェクトは、作成されたスレッド/キューからアクセスする必要があります。

+0

お返事ありがとうございました。だから、基本的には私の実行ブロックから何かオブジェクトを出すことは許されていないのですか? – TMob

+0

正しい。通常は、同じコンテキスト内で呼び出された補完ブロックを使用するか、 'objectID'を渡して別のコンテキストに再フェッチします。 – Avi

+0

ああああ。私たちは多くのソフトウェアアーキテクチャを改造しなければならないと思います。ありがとうございました – TMob

0

plz managedObjectContextを取得するには、このコードを使用します。マネージオブジェクトは、作成されたスレッド/キューからアクセスする必要があります。

- (NSManagedObjectContext *)managedObjectContext 
    { 
     NSThread *thisThread = [NSThread currentThread]; 
     if (thisThread == [NSThread mainThread]) 
     { 

      if (_managedObjectContext != nil) { 
       return _managedObjectContext; 
      } 
      // 
      if ([self persistentStoreCoordinator] != nil) { 
       _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
       [_managedObjectContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]]; 
      } 
      [_managedObjectContext setRetainsRegisteredObjects:YES]; 
      [_managedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 
      return _managedObjectContext; 

     } 
     else 
     { 
      //Return separate MOC for each new thread 
      NSManagedObjectContext *threadManagedObjectContext = [[thisThread threadDictionary] objectForKey:@"MOC_KEY"]; 
      if (threadManagedObjectContext == nil) 
      { 
       threadManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
       NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
       [threadManagedObjectContext setPersistentStoreCoordinator: coordinator]; 
       [[thisThread threadDictionary] setObject:threadManagedObjectContext forKey:@"MOC_KEY"]; 

      } 

      return threadManagedObjectContext; 
     } 
    } 
+0

私は既にこのようなものが実装されています。 @Aviが指摘したように、これはここでは問題ではないようですが、むしろアーキテクチャの誤解です。 – TMob

関連する問題