【问题标题】:Could not delete core data PersistentStore无法删除核心数据 PersistentStore
【发布时间】:2015-11-13 04:17:59
【问题描述】:

我想彻底删除应用 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];

结果是控制台中没有出现错误,但它只是删除了主存储文件:“model.sqlite”和其他2个相关文件:“model.sqlite-shm”和“model.sqlite-wal”仍然存在。

当我通过相同的代码调用“removeStorage2”方法时,我在控制台上看到以下文本并且没有删除任何文件:

Could not remove Storage. Reason: (null)

我该如何解决这个问题?

【问题讨论】:

  • 您只需调用NSFileManager 即可删除一个文件。您为什么希望它删除其他任何内容?
  • 是的,在以前的 iOS 版本中,只使用一个文件,并且 removeStorage 方法会这样做,但现在为了删除所有文件,我使用了第二种方法 removeStorage2,但它不起作用。请重新检查以获取更多详细信息:stackoverflow.com/questions/1077810/…

标签: objective-c core-data


【解决方案1】:

观看视频“Straight outta Moscone Center West”以获取有关您应该如何执行此操作的官方介绍,和/或咨询从中提取以下 sn-p 的 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);

【讨论】:

  • 除了文件被截断而不是为 sqlite 商店物理删除之外,我还注意到一些意外行为(iOS 10):使用指向实际上并不存在的文件的 URL 调用此方法存在,而不是失败(或什么都不做),结果是一个空的 sqlite 存储被创建
猜你喜欢
  • 2017-03-20
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多