2011-09-16 41 views
1

我想刪除我的sql lite文件並重新設置持久性存儲。刪除先前的sqlite存儲文件後重新創建持久性存儲

//Explicitly write Core Data accessors 

- (NSManagedObjectContext *) managedObjectContext { 
if (managedObjectContext != nil) { 

    return managedObjectContext; 

} 

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 

if (coordinator != nil) { 

    managedObjectContext = [[NSManagedObjectContext alloc] init]; 

    [managedObjectContext setPersistentStoreCoordinator: coordinator]; 
} 

    return managedObjectContext; 
} 

- (void) setManagedObjectContext:(NSManagedObjectContext *)managedObjectContext{} 


- (NSManagedObjectModel *)managedObjectModel { 
    if (managedObjectModel != nil) { 
     return managedObjectModel; 
    } 
managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil] ; 

    return managedObjectModel; 
} 

-(void) setManagedObjectModel:(NSManagedObjectModel *)managedObjectModel{} 


- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { 
    if (persistentStoreCoordinator != nil) { 
     return persistentStoreCoordinator; 
    } 
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Port.sqlite"]];  
    NSError *error = nil; 
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
    if(![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) { 

     NSLog(@"Could not create store .... %@", error); 
     /*Error for store creation should be handled in here*/ 
    } 

return persistentStoreCoordinator; 
} 

我想重置我的場景是這樣

- (void)reset { 
    // Release CoreData chain 
    self.managedObjectContext = nil; 
    self.managedObjectModel = nil; 
    self.persistentStoreCoordinator = nil; 

    // Delete the sqlite file 
    NSError *error = nil; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"Port.sqlite"]]; 

    if ([fileManager fileExistsAtPath:storeUrl.path]){ 
     [fileManager removeItemAtURL:storeUrl error:&error]; 
    } 
    self.managedObjectContext = [self managedObjectContext]; 
    self.managedObjectModel = [self managedObjectModel]; 
    self.persistentStoreCoordinator = [self persistentStoreCoordinator]; 

    // handle error... 
} 

同時節省我得到一個錯誤:

+ (BOOL)saveAll { 
    // [self createStorage]; 
    NSError *error = nil; 
    NSManagedObjectContext *managedObjectContext = [(WSSMobileAppsAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
    if (![managedObjectContext save:&error]) { 
     NSLog(@"Error while saving %@", error); 
     return FALSE; 
    } 
    return TRUE; 
} 

錯誤:

Error while saving Error Domain=NSCocoaErrorDomain Code=134030 "The operation couldn’t be completed. (Cocoa error 134030.)" UserInfo=0x7195ac0 {NSAffectedStoresErrorKey=(
    "<NSSQLCore: 0x714eee0> (URL: file://localhost/Users/.../Library/Application%20Support/iPhone%20Simulator/5.0/Applications/CEDB9019-1D64-4968-9BE7-57E1493B96EC/Documents/Port.sqlite)" 
), NSUnderlyingError=0x7195a50 "The operation couldn’t be completed. (Cocoa error 4.)", NSFilePath=/Users/.../Library/Application Support/iPhone Simulator/5.0/Applications/CEDB9019-1D64-4968-9BE7-57E1493B96EC/Documents/Port.sqlite} 

我只如果我運行我的重置功能,會得到錯誤。我認爲設置:

self.managedObjectContext = nil; 
self.managedObjectModel = nil; 
self.persistentStoreCoordinator = nil; 

...將解決問題。然後一切都會重新創建。請幫忙。


非常感謝您的回答。現在沒有錯誤,但是如果我運行重置,則不會有任何存儲。我在保存後立即執行提取操作

if (![managedObjectContext save:&error]) { 
    NSLog(@"Error while saving %@", error); 
    return FALSE; 
} 
CoreDataPortService *c = [[CoreDataPortService alloc] init]; 
NSLog(@"Saved all.... got number of ports ... %d", [[c getPorts] count]); 

我如果不運行我的重置方法,一切都按預期工作。什麼可能是錯誤的?

+0

我認爲這一點是你想刪除所有的數據。沒有?如果刪除該文件並刪除內存中的managedObjectContext,則數據將消失。如果你想刪除文件並從內存中重新創建文件,那麼你需要一種不同的方法。我無法想象爲什麼你會這麼做。在正常情況下,持久性存儲將與您在託管對象上下文中保持同步。 – morningstar

+0

我想刪除這些數據。是否也可以刪除文件。那是因爲有時候我改變實體。 – pethel

+0

你說,「如果我運行我的重置,沒有任何東西被存儲」。聽起來你不想存儲任何內容,即刪除了所有內容。你的意思是你運行重置,然後添加對象,然後保存,並且之後沒有對象? – morningstar

回答

0

你寫了一個二傳手您managedObjectContext,但不起任何作用:

- (void) setManagedObjectContext:(NSManagedObjectContext *)managedObjectContext{} 

當你這樣做self.managedObjectContext = nil,它是所有調用[self setManagedObjectContext:nil]。那什麼都不做。實例變量managedObjectContext保持相同的值,並且當您使用getter再次請求它時,您仍然擁有與刪除的文件關聯的managedObjectContext。您需要:

- (void) setManagedObjectContext:(NSManagedObjectContext *)_managedObjectContext { 
    [managedObjectContext release]; 
    managedObjectContext = _managedObjectContext; 
    [managedObjectContext retain]; 
} 

而且還假設您的managedObjectContext屬性是使用非原子修飾符聲明的。如果它被聲明爲原子的,你還需要代碼來鎖定。以類似的方式編寫managedObjectModel和persistentStoreCoordinator的setter。

@synthesize通常會爲您生成這樣的setter,但由於您想編寫自己的getter,因此您也必須編寫自己的setter。可能有一種方法讓@synthesize改爲只爲你的屬性設置setter,但我不記得了。

回答後續問題。也許你正在做這樣的事情:

NSManagedObjectContext *moc = self.managedObjectContext; 
[self reset]; 
[self repopulateData:xmlFile]; 
NSError *error = nil; 
if (![moc save:&error]) 
    [self logError:error]; 

如果是這種情況,那麼你會調用保存在舊的託管對象的上下文。不確定那會是什麼結果。改爲將倒數第二行改爲

if (![self.managedObjectContext save:&error]) 

確保您使用的是當前託管對象上下文。

或者您可能試圖從舊的託管對象上下文中讀取。檢查您正在使用的任何託管對象上下文指針的地址,並確保它們指向與您在重置時創建的新託管對象上下文相同的內容。

如果這不是問題,我不知道。你將不得不嘗試收集更多的信息,爲什麼它不工作。例如,文件是否存在?添加數據時其大小是否增加?數據是否寫入文件,但無法讀取?

+1

小問候。這是不正確的,如果你想要自定義getter,你也必須編寫自定義setter(反之亦然)。如果所需的方法不存在,@sythesize會創建它,如果存在,它會使用該方法。你可以混合和匹配所有你想要的。 – TechZen

+0

好的,那是更好的答案。刪除' - (void)setManagedObjectContext:(NSManagedObjectContext *)managedObjectContext {}'並添加'@synthesize managedObjectContext'。 – morningstar

+0

非常感謝你的回答。 – pethel