2015-11-12 135 views
0

我想徹底刪除應用程序PersistentStore。我仔細閱讀以下問題和他們都不工作:無法刪除核心數據PersistentStore

Delete/Reset all entries in Core Data?

我有一個模型助手,做刪除任務裏面:

#import <CoreData/CoreData.h> 

@interface GeneralModel : NSFetchedResultsController 

@property (nonatomic, strong) NSManagedObjectContext *context; 
@property (nonatomic, strong) NSManagedObjectModel *model; 

- (NSString *)storagePath; 
- (void)removeStorage; 
- (void)removeStorage2; 
@end 

@implementation GeneralModel 

- (instancetype)init 
{ 
    self = [super init]; 
    if (self) { 
     // Read in Model.xcdatamodeld 
     _model = [NSManagedObjectModel mergedModelFromBundles:nil]; 
     NSPersistentStoreCoordinator *psc = 
     [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_model]; 

     // Where does the SQLite file go? 
     NSString *path = self.storagePath; 
     NSURL *storeURL = [NSURL fileURLWithPath:path]; 
     NSError *error = nil; 
     if (![psc addPersistentStoreWithType:NSSQLiteStoreType 
           configuration:nil 
             URL:storeURL 
            options:nil 
             error:&error]) { 
      @throw [NSException exceptionWithName:@"OpenFailure" 
              reason:[error localizedDescription] 
             userInfo:nil]; 
     } 

     // Create the managed object context 
     _context = [[NSManagedObjectContext alloc] init]; 
     _context.persistentStoreCoordinator = psc; 

    } 
    return self; 
} 

- (NSString *)storagePath 
{ 
    NSArray *documentDirectories = 
    NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
             NSUserDomainMask, 
             YES); 
    // Get one and only document directory from that list 
    NSString *documentDirectory = [documentDirectories firstObject]; 
    return [documentDirectory stringByAppendingPathComponent:@"model.sqlite"]; 
} 

- (void)removeStorage { 

    NSPersistentStore *store = [self.context.persistentStoreCoordinator.persistentStores lastObject]; 
    NSError *error = nil; 
    NSURL *storeURL = store.URL; 
    BOOL isRemovePersistentStore = [self.context.persistentStoreCoordinator removePersistentStore:store error:&error]; 
    if (isRemovePersistentStore == NO) { 
     NSLog(@"NO RemovePersistentStore. Reason: %@", error.localizedFailureReason); 
    } 

    BOOL isRemoveItemAtURL = [[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error]; 
    if (isRemoveItemAtURL == NO) { 
     NSLog(@"NO RemoveItemAtURL. Reason: %@", error.localizedFailureReason); 
    } 
} 

- (void)removeStorage2 { 
    NSError *error; 
    NSString *storagePath = [self storagePath]; 

    NSDictionary *options = @{NSPersistentStoreUbiquitousContentNameKey: @"model"}; 
    bool removeResult = [NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:[NSURL URLWithString:storagePath] options:options error:&error]; 
    if (removeResult == NO) { 
    NSLog(@"Could not remove Storage. Reason: %@", error.localizedFailureReason); 
    } 
} 

@end 

當我稱之爲「removeStorage」方法,通過下面的代碼:

GeneralModel *model = [[GeneralModel alloc] init]; 
[model removeStorage]; 

結果是沒有錯誤在控制檯apear,但它只是刪除了主存儲文件:「model.sqlite」和2個OTH呃相關的文件:「model.sqlite-shm」和「model.sqlite-wal」仍然存在。

當我調用由同一代碼「removeStorage2」的方法,我看到控制檯並沒有任何文件的以下文本刪除:

Could not remove Storage. Reason: (null) 

我怎麼能解決這個問題?

+0

您只調用'NSFileManager'來刪除一個文件。你爲什麼期望它刪除其他東西? – Avi

+0

是的,在以前的iOS版本中,只有一個文件被使用,removeStorage方法會這樣做,但現在要刪除所有使用第二種方法removeStorage2的文件,並且它不起作用。請重新檢查它的更多細節:http://stackoverflow.com/questions/1077810/delete-reset-all-entries-in-core-data –

回答

1

查看視頻「Straight outta Moscone Center West」,以便正式介紹如何進行此操作,和/或諮詢NSPersistentStoreCoordinator.h,其中摘錄了以下代碼段。

/* delete or truncate the target persistent store in accordance with the store 
    class's requirements. It is important to pass similar options as 
    addPersistentStoreWithType: ... SQLite stores will honor file locks, journal 
    files, journaling modes, and other intricacies. It is not possible to unlink 
    a database file safely out from underneath another thread or process, so this 
    API performs a truncation. Other stores will default to using NSFileManager. 
*/ 
- (BOOL)destroyPersistentStoreAtURL:(NSURL *)url 
          withType:(NSString *)storeType 
          options:(nullable NSDictionary *)options 
           error:(NSError**)error NS_AVAILABLE(10_11, 9_0); 

/* copy or overwrite the target persistent store in accordance with the store 
    class's requirements. It is important to pass similar options as 
    addPersistentStoreWithType: ... SQLite stores will honor file locks, journal 
    files, journaling modes, and other intricacies. Other stores will default 
    to using NSFileManager. 
*/ 
- (BOOL)replacePersistentStoreAtURL:(NSURL *)destinationURL 
       destinationOptions:(nullable NSDictionary *)destinationOptions 
     withPersistentStoreFromURL:(NSURL *)sourceURL 
         sourceOptions:(nullable NSDictionary *)sourceOptions 
          storeType:(NSString *)storeType 
           error:(NSError**)error NS_AVAILABLE(10_11, 9_0); 
+0

除了文件被截斷,而不是物理刪除的sqlite商店,我我們注意到一些意外的行爲(iOS 10): 使用指向一個實際不存在的文件的URL調用此方法,而不是失敗(或什麼都不做),結果是一個空的*正被創建的sqlite存儲* 。 – MathewS