即使验证失败,Core Data 也会保存对象

Posted

技术标签:

【中文标题】即使验证失败,Core Data 也会保存对象【英文标题】:Core Data saves object even when validation fails 【发布时间】:2010-10-22 20:25:31 【问题描述】:

我已经包含了处理所有保存功能的函数。

这是我的问题。

我正在抓取 5 个输入值并将其保存为 CoreData 日志实体。

即使 Log 对象验证失败,当我退出表单并查看表格视图时,它仍然被保存。

如何强制 Core Data 仅在对象经过验证后才保存它?

-(void) saveLog 
    NSManagedObjectContext *managedObjectContext = [(AppDelegate_Shared *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 

    FormPickerCell *bloodPressure = (FormPickerCell *) [self.formController fieldAsObject:@"bloodpressure"];


    NSInteger systolic = [(PressureDataSource*)bloodPressure.pickerCellDelegate selectedSystolicPressureForFormPickerCell:bloodPressure];
    NSInteger diastolic = [(PressureDataSource*)bloodPressure.pickerCellDelegate selectedDiastolicPressureForFormPickerCell:bloodPressure];
    NSLog(@"bp is %d / %d", systolic, diastolic);
    NSLog(@"date is %@", [self.formController valueForField:@"date"]);

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss ZZZ"];

    if (self.isNewLog && !self.validationHasFailed) 
        self.log = [NSEntityDescription
                     insertNewObjectForEntityForName:@"Log" inManagedObjectContext:managedObjectContext];

    

    NSString *heartRate = [[self.formController valueForField:@"heartrate"] stringByReplacingOccurrencesOfString:@" bpm" withString:@""];

    NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
    [f setNumberStyle:NSNumberFormatterDecimalStyle];

    self.log.created        = [NSDate date];
    self.log.notes          = [self.formController valueForField:@"notes"];
    self.log.systolic       = [NSNumber numberWithInteger:systolic];
    self.log.diastolic      = [NSNumber numberWithInteger:diastolic];
    self.log.stressLevel    = [self.formController valueForField:@"stresslevel"];
    self.log.logDate        = [dateFormatter dateFromString:[self.formController valueForField:@"date"]];
    self.log.heartrate      = [f numberFromString:heartRate];
    NSLog(@"Log date is %@",[self.formController valueForField:@"date"]);

    [f release];

    NSError *error;
    NSString *title;
    NSString *growlDescription;

    if ([self.log validateForInsert:&error])
        NSLog(@"after validation returned true");
        if(![managedObjectContext save:&error]) 
            NSLog(@"Unresolved error");
            title = @"Error Occurred";
            growlDescription = [error localizedDescription];
            self.validationHasFailed = YES;
         else 
            title = @"Log Saved!";
            growlDescription = @"Log saved successfully";
            [self.navigationController popViewControllerAnimated:YES];
               
     else 
        NSLog(@"after validation returned false");
        NSLog(@"Unresolved error");
        title = @"Error Occurred";
        growlDescription = [error localizedDescription];
        self.validationHasFailed = YES;
    

    IZGrowlNotification *notification = [[IZGrowlNotification alloc] initWithTitle:title 
                                                                       description:growlDescription
                                                                             image:nil
                                                                           context:nil 
                                                                          delegate:self];
    [[IZGrowlManager sharedManager] postNotification:notification];
    [notification release];     
    error = nil;    





【问题讨论】:

【参考方案1】:

这有点晚了,但我刚看到你的问题,所以想我会给你一个答案。您添加到托管对象上下文的任何对象都将在您下次保存时保存。您可以保留您的代码,只需使用 [managedObjectContext deleteObject:self.log] 删除新对象,但下面是更好的方法。

您的代码:

self.log = [NSEntityDescription insertNewObjectForEntityForName:@"Log" inManagedObjectContext:managedObjectContext];

创建一个新的Log 实例并插入到托管对象上下文中。你想要做的是:

self.log = [[Log alloc] initWithEntity:[NSEntityDescription entityForName:@"Log" inManagedObjectContext:managedObjectContext] insertIntoManagedObjectContext:nil];

这将创建一个尚未插入 MOC 的新“日志”实例。如果验证成功,则在保存 MOC 之前插入 self.log,如下所示:

[managedObjectContext insertObject:self.log];

然后你保存。如果验证失败,请不要插入对象,一切顺利。

【讨论】:

initWithEntity 至少在 ios 6.1 中是一个实例方法(不是如图所示的类方法)

以上是关于即使验证失败,Core Data 也会保存对象的主要内容,如果未能解决你的问题,请参考以下文章

即使设置了 cookie,RabbitMQ 身份验证也会失败

即使在删除之后,Core Data 命令也会使 ViewController 崩溃

即使由于错误导致插入失败,MySQL 自动增量值也会增加

即使在 asp.net core 5.0 中提供了不记名令牌,也会返回 401 [关闭]

即使存在未设置为true,Rails验证也需要数值

即使输入无效,AngularJS表单也会验证