2011-07-14 71 views
2

我目前正在開發一個使用核心數據的應用程序。我正在使用兩個商店/配置,一個用於靜態內容,另一個用於用戶內容。偶爾在啓動時,我得到一個崩潰,說「不能添加同一商店兩次」。我一直無法追蹤或定期重複,所以我想知道是否有人能夠發現任何見解?這只是一個發佈漏洞,在發佈後會消失(不太可能,我知道)。有沒有什麼不對的地方可以用我的代碼看到,以創建持久性商店?無法將商店添加兩次

另一件值得一提的事情是,我將所有的Core Data訪問代碼都包裝在一個singleton類中。我想,有可能兩個線程非常接近地訪問managedObjectContext,導致幾乎同時訪問persistentStoreCoordinator

注: sharedPaths是短路徑名稱的數組,例如。 @"Data_Static", @"Data_User" sharedConfigurations是一組配置名稱,例如。 @"Static", @"User"

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { 
if (_persistentStoreCoordinator != nil) { 
    return _persistentStoreCoordinator; 
} 

NSString* documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 
NSFileManager* fileManager = [NSFileManager defaultManager]; 
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];  
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]]; 

//load each store/configuration 
for(int i=0; i<[sharedPaths count]; i++) { 
    NSString* path = [sharedPaths objectAtIndex:i]; 
    NSString* configuration = nil; 
    if([sharedConfigurations count] > 0) { 
     configuration = [sharedConfigurations objectAtIndex:i]; 
    } 

    NSString* storePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.sqlite", path]]; 
    //if the store doesn't exist, copy over the default store 
    if(![fileManager fileExistsAtPath:storePath]) { 
     NSString* defaultStorePath = [[NSBundle mainBundle] pathForResource:path ofType:@"sqlite"]; 
     if(defaultStorePath) { 
      [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL]; 
     } 
    } 

    NSURL* storeURL = [NSURL fileURLWithPath:storePath]; 
    NSError* error = nil; 
    if(![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:configuration URL:storeURL options:options error:&error]) { 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     exit(-1); 
    } 
} 

return _persistentStoreCoordinator; 

}

回答

14

如果你認爲這是一個線程的問題,把它變成一個synchronized塊:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { 
    @synchronized(self) { 

     if (_persistentStoreCoordinator != nil) { 
      return _persistentStoreCoordinator; 
     } 

     ... 

    } 
} 

這將阻止兩個線程同時運行的代碼。

(您可能需要這種模式添加到不能被不同的線程同時運行任何其他方法。)

+0

這只是懷疑,誤差僅出現每隔一陣子(這使我更可疑這是一個線程問題)。我想我可以試試這個,看看它是否阻止我看到錯誤... –

+0

我最終評論了'if(_persistentStoreCoordinator!= nil)'塊,並且對'managedObjectModel'和'managedObjectContext' ,並能夠重複這個問題。所以我認爲你讓我走上正軌,謝謝。我已經同步了持久性存儲,以及託管對象模型和上下文,我相當肯定應該修復它。 –