【问题标题】:core data not saving when I want to核心数据在我想保存时没有保存
【发布时间】:2017-02-13 15:19:44
【问题描述】:

我正在开发一个保存医疗记录的应用。我正在使用具有单个上下文和单个物理存储的核心数据。尽管调用了 [managedObjectContext save:&error],但如果我通过 Xcode 提取容器,sqlite db 不会显示最新数据。

尝试了类似此处建议的方法:Core data not saving my data,但对我来说并不奏效。 更糟糕的是,数据确实会在一段时间后出现:应用程序可以通过 FTP 发送 sqlite 以转储数据以进行灾难恢复。碰巧上周的工作并不总是出现,但通常会在一周后出现。

我不明白的是:[managedObjectContext save:&error] 是否立即将数据写入实体店? (我的猜测是否定的) 我如何告诉核心数据我想当场写下我的数据(假设它实际上是可能的)? 关闭应用程序和/或重新启动设备是否会使核心数据写入 sqlite?

编辑 1 - 添加一些代码 [managedObjectContext save:&error] 在 [CommonHelper SaveData:true] 中被调用;就在@try 块的开头。

_FollowUp.bMI=[NSNumber numberWithFloat: [TextBMI.text floatValue]];
    _FollowUp.karfnosky=[NSNumber numberWithInt: [TextKarfnosky.text intValue]];
    _FollowUp.charlson=[NSNumber numberWithInt: [TextCharlson.text intValue]];
    _FollowUp.alimentazione=ButtonAlimentazione.titleLabel.text;
    _FollowUp.farmaci=TextFarmaci.text;
    _FollowUp.dolore=ButtonDolore.titleLabel.text;


    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];


    @try {
        [CommonHelper SaveData:true];            


        UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@“Data saved” message: @“Record saved successfully” delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
        [alert show];


        float height = self.view.bounds.size.height;
        float width = self.view.bounds.size.width;
        lblSincro = [[UILabel alloc]initWithFrame:CGRectMake(width/2-200 ,height/2+30, 400, 20)];
        lblSincro.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        lblSincro.font = [UIFont boldSystemFontOfSize:16.0f];
        lblSincro.numberOfLines = 1;
        [lblSincro setTextAlignment:NSTextAlignmentCenter];
        lblSincro.backgroundColor = [UIColor clearColor];
        lblSincro.textColor = [UIColor whiteColor];
        lblSincro.text = @"Uploading in progress";

        UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] ;
        spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge] ;
        spinner.frame = CGRectMake(0, 0,  width,height);
        spinner.tag = 3;
        UIColor *color = [[UIColor alloc] initWithRed:0.0 green:0.0 blue:0.0 alpha:0.5];
        spinner.backgroundColor =color;

        lblSincroDet = [[UILabel alloc]initWithFrame:CGRectMake(width/2-200 ,height/2+70, 400, 20)];
        lblSincroDet.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        lblSincroDet.font = [UIFont boldSystemFontOfSize:16.0f];
        lblSincroDet.numberOfLines = 1;
        [lblSincroDet setTextAlignment:NSTextAlignmentCenter];
        lblSincroDet.backgroundColor = [UIColor clearColor];
        lblSincroDet.textColor = [UIColor whiteColor];

        [self.view addSubview:lblSincro];
        [self.view addSubview:lblSincroDet];
        [self.view addSubview:spinner];

        [spinner addSubview:lblSincro];
        [spinner addSubview:lblSincroDet];

        [spinner startAnimating];

        dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){

            SyncHelper *sync=[SyncHelper alloc];
            BOOL result=sync.Sincronize;

            dispatch_async(dispatch_get_main_queue(), ^(void){
                [spinner stopAnimating];
                [lblSincro removeFromSuperview];
                [lblSincroDet removeFromSuperview];

                [lblSincro removeFromSuperview];
                if(result){
                    _SaveView  = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"successSincro", @"") message:NSLocalizedString(@"successSincroMessage", @"") delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                    [_SaveView show];
                }else{
                    _SaveView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"failedSincro", @"") message:NSLocalizedString(@"failedSincroMessage", @"")
                                                          delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
                    [_SaveView show];
                }
            });
        });
        _FollowUpLoad=_FollowUp;
        _isNew=false;
    }@catch (NSException *ex)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message: @“Failed to save data” delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
        [alert show];
    }

【问题讨论】:

  • 你在后台队列中做一些处理吗?
  • 没什么重要的,只有进度条之类的东西。
  • 你显示插入方法你在哪里保存?
  • 添加代码:我将数据保存在@try块的开头
  • CommonHelper 是你的实体对象吗?

标签: sqlite core-data managedobjectcontext


【解决方案1】:

你必须根据他们保存的线程来访问 NSManagedObjectContext。 阅读此链接。

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/Concurrency.html

将您的数据插入主队列

            dispatch_async(dispatch_get_main_queue(), ^{

          [CommonHelper SaveData:true];

            });

希望它的工作。

【讨论】:

    【解决方案2】:

    CoreData 默认使用Write-Ahead Logging,因此.sqlite 文件不会总是包含您的所有数据,除非您禁用它。

    就这样……

    NSDictionary *options = @{
         NSMigratePersistentStoresAutomaticallyOption : @YES,
         NSInferMappingModelAutomaticallyOption : @YES,
         NSSQLitePragmasOption: @{@"journal_mode": @"DELETE"}
    };
    [persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]
    

    【讨论】:

    • 抱歉来晚了,我自己研究了一下,发现SQLite正在使用WAL。数据正在保存,我只需要导出 .sqlite-shm 和 .sqlite-wal 以及 .sqlite 文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多