2016-07-12 48 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-concurrency和object-release有沒有什麼特別的東西? 我環顧四周,沒有任何關於對象釋放的提及,只關於我不使用的autoreleasepools。

回答

2

您正在執行performBlockAndWait:調用中的工作,這是正確的。但是,您繼續返回對象,可能來自不同的線程。這不合法。必須從創建它們的線程/隊列訪問所有受管理對象,但objectID屬性始終有效。

+0

感謝您的快速響應。所以基本上我不允許從我的執行塊中提取任何對象? – TMob

+0

正確。通常的做法是使用在同一個上下文中調用的完成塊,或者將'objectID's和refetch傳遞到不同的上下文中。 – Avi

+0

哦,很無趣。我想我們必須改造我們的很多軟件架構。非常感謝 – TMob

0

plz使用此代碼獲取managedObjectContext.managed對象必須從創建它們的線程/隊列訪問。

- (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