如何获取存储在 iOS 持久性 sqlite 数据库中的值?

Posted

技术标签:

【中文标题】如何获取存储在 iOS 持久性 sqlite 数据库中的值?【英文标题】:How to get values stored in iOS persistent sqlite database? 【发布时间】:2017-01-05 20:05:44 【问题描述】:

我有一个 ios 持久性 sqlite 数据库,我无法删除存储的数据:

    #import "DB.h"
    #import 

    @interface DB ()
    
        NSString* db_title;
        NSURL* db_store_url;
        NSURL* db_model_url;

        NSPersistentStoreCoordinator* db_persistent_store_coordinator;
        NSManagedObjectModel* db_managed_object_model;
        NSManagedObjectContext* db_managed_object_context;
        NSFetchedResultsController* db_fetched_results_controller;
        NSFetchRequest* db_fetch_request;
        NSEntityDescription* db_entity_description;
        NSSortDescriptor* db_sort_descriptor;
        NSArray* db_sort_descriptors;
    
    @end

    @implementation DB

    -(instancetype)init
    
        NSLog(@"[%s]", __FUNCTION__);

        self = [super init];

        db_title = @"AlarmButtons";
        db_store_url = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:@"AlarmButtons.sqlite"];
        db_model_url = [[NSBundle mainBundle] URLForResource:db_title withExtension:@"momd"];

        return self;
    

    -(void) delete_database_file
    
        NSLog(@"[%s]", __FUNCTION__);

        NSError* error;

        if(![[NSFileManager defaultManager] removeItemAtURL:db_store_url error:&error])
        
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        
    

    -(void) load_database_file
    
        NSLog(@"[%s]", __FUNCTION__);

        NSError* error;

        NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

        db_managed_object_model = [[NSManagedObjectModel alloc] initWithContentsOfURL:db_model_url];

        db_persistent_store_coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:db_managed_object_model];

        if(![db_persistent_store_coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:db_store_url options:options error:&error])
        
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

            if(![[NSFileManager defaultManager] removeItemAtURL:db_store_url error:&error])
            
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            

            if(![db_persistent_store_coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:db_store_url options:nil error:&error])
            
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            
        

        db_managed_object_context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        [db_managed_object_context setPersistentStoreCoordinator:db_persistent_store_coordinator];

        db_fetch_request = [[NSFetchRequest alloc] init];
        db_entity_description = [NSEntityDescription entityForName:db_title inManagedObjectContext:db_managed_object_context];

        [db_fetch_request setEntity:db_entity_description];
        [db_fetch_request setFetchBatchSize:20];

        db_sort_descriptor = [[NSSortDescriptor alloc] initWithKey:@"register_id" ascending:YES];
        db_sort_descriptors = @[db_sort_descriptor];

        [db_fetch_request setSortDescriptors:db_sort_descriptors];

        db_fetched_results_controller = [[NSFetchedResultsController alloc] initWithFetchRequest:db_fetch_request managedObjectContext:db_managed_object_context sectionNameKeyPath:nil cacheName:@"Master"];

        if(![db_fetched_results_controller performFetch:&error])
        
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        

    

    -(void) save
    
        NSLog(@"[%s]", __FUNCTION__);

        NSError* error;

        if([db_managed_object_context hasChanges] && ![db_managed_object_context save:&error])
        
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        
    

    -(void) insert
    
        NSLog(@"[%s]", __FUNCTION__);

        NSManagedObject* new_managed_object = [NSEntityDescription insertNewObjectForEntityForName:[[[db_fetched_results_controller fetchRequest] entity] name] inManagedObjectContext:db_managed_object_context];

        [new_managed_object setValue:@"1" forKey:@"register_id"];
        [new_managed_object setValue:@"2" forKey:@"button_id"];
        [new_managed_object setValue:@"3" forKey:@"server_id"];
        [new_managed_object setValue:@"4" forKey:@"password"];

        NSLog(@"+register_id: %@", [new_managed_object valueForKey:@"register_id"]);
        NSLog(@"+button_id: %@", [new_managed_object valueForKey:@"button_id"]);
        NSLog(@"+server_id: %@", [new_managed_object valueForKey:@"server_id"]);
        NSLog(@"+password: %@", [new_managed_object valueForKey:@"password"]);

        [self save];
    

    -(int) count_entities
    
        NSLog(@"[%s]", __FUNCTION__);

        NSError *error;
        NSUInteger count = [db_managed_object_context countForFetchRequest:db_fetch_request error:&error];
        if(count == NSNotFound) 
            NSLog(@"count: NSNotFound!");
            return 0;
        
        else
        
            NSLog(@"count: %d", count);        
        
        return count;
    

    -(void) remove
    
        NSLog(@"[%s]", __FUNCTION__);
        [db_managed_object_context deleteObject:[db_fetched_results_controller objectAtIndexPath:[[NSIndexPath alloc] initWithIndex:0]]];
    

    @end
    

[-[数据库删除]] 2017-01-05 20:49:18.380089 应用程序 [422:55746] [错误] 错误:NSFetchedResultsController:索引 0 部分中索引 2147483647 处没有对象 2017-01-05 20:49:18.381024 App[422:55746] * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“索引 0 部分中索引 2147483647 处没有对象” * 首先抛出调用栈: (0x1d47ee07 0x1c6df077 0x1f3f8185 0xf9a55 0xf8485 0x224d7123 0x224d6d0f 0x2260fe09 0x2260fba5 0x2260fa13 0x226127f7 0x224e4f1b 0x2261442d 0x22613199 0x224eed2f 0x224eeaed 0x2258e6e9 0x2258df2d 0x2258db1f 0x2258da99 0x224d45d5 0x202fa109 0x202ee31f 0x202ee1af 0x2027ea6b 0x2029d035 0x2029dad3 0x1d43a485 0x1d438701 0x1d388093 0x1d387e81 0x225428c9 0x2253cf61 0xf9f57 0x1cb5250b) libc++abi.dylib:以 NSException 类型的未捕获异常终止 (lldb)

我错过了什么?数据显然存储成功。

【问题讨论】:

【参考方案1】:

你正在构造一个长度为 1 的 indexPath;获取的结果控制器需要长度为 2 的 indexPath(表示节和行)。修改你的remove方法如下:

-(void) remove

    NSLog(@"[%s]", __FUNCTION__);
    NSUInteger indexes[] = 0,0;
    NSIndexPath *ip = [NSIndexPath indexPathWithIndexes:indexes length:2];
    [db_managed_object_context deleteObject:[db_fetched_results_controller objectAtIndexPath:ip]];

正如@TomHarrington 在 cmets 中指出的那样,您也可以使用:

    NSIndexPath *ip = [NSIndexPath indexPathForRow:0 inSection:0];

虽然您可能还需要导入 UIKit 才能使其正常工作。

【讨论】:

使用[NSIndexPath indexPathForRow:0 inSection:0] 会更清楚地说明索引的含义。 @TomHarrington 是的,但我注意到 OP 的代码没有(出于某种原因)导入 UIKit(我相信它提供了对 NSIndexPath 的扩展)。但为了清楚起见,我会添加它。 这是最好的答案,而且有效!!非常感谢!!

以上是关于如何获取存储在 iOS 持久性 sqlite 数据库中的值?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 CoreData SQLite 支持的持久存储克隆到“内存中”?

持久化存储

CBD Store 作为 iOS 中核心数据的持久存储

如何在 WatchKit 扩展目标中获取核心数据持久存储路径

XCode 4.3 无法加载持久存储 UserDictionary.sqlite

我应该如何命名可导入的.sqlite持久存储?