Ios 使用键值编码的核心数据验证

Ios 使用键值编码的核心数据验证,ios,validation,core-data,kvc,Ios,Validation,Core Data,Kvc,我创建了一个核心数据模型,并创建了一个category类,其中包含更新和删除数据的方法。我试图向类中添加验证方法,并尝试使用KVC,但有点困难 我的问题是,我的验证方法只有在实际保存上下文[context save:&internalError]时才会触发,它们工作正常,但保存过程也完成了。我的问题是,什么时候触发验证?它是在保存之前触发的,还是我完全错了 我的代码: +(int)doSmeThing:(InstructionMessageObject *)message inManagedOb

我创建了一个核心数据模型,并创建了一个category类,其中包含更新和删除数据的方法。我试图向类中添加验证方法,并尝试使用KVC,但有点困难

我的问题是,我的验证方法只有在实际保存上下文[context save:&internalError]时才会触发,它们工作正常,但保存过程也完成了。我的问题是,什么时候触发验证?它是在保存之前触发的,还是我完全错了

我的代码:

+(int)doSmeThing:(InstructionMessageObject *)message inManagedObjectContext:(NSManagedObjectContext *)context error:(NSError **)error {

    NSError *internalError = nil;    
    int timeStamp = [[NSDate date] timeIntervalSince1970];

    NSManagedObject *newMessageObject = [NSEntityDescription insertNewObjectForEntityForName:@"CoreDataTable"inManagedObjectContext:context];    
    [newMessageObject setValue:message.productCode forKey:@"productCode"];
    [newMessageObject setValue:message.quantity  forKey:@"quantity"];

///////////////////////////////////////
// Need to validate HERE before save //
///////////////////////////////////////

    if (![context save:&internalError]) {
        *error = internalError;
    return NO;
    }

    return YES;
}


- (BOOL)validateProductCode:(id *)ioValue error:(NSError **)outError {
    *outError = nil;
    if ([*ioValue integerValue] < 1 ) {
        *outError = [NSError errorWithDomain:@"domain" code:101 userInfo:[NSDictionary dictionaryWithObject:@"Invalid Product Code" forKey:NSLocalizedDescriptionKey]];
        return NO;
    }
    return YES;
}

- (BOOL)validateQuantity:(id *)ioValue error:(NSError **)outError {
    *outError = nil;
    if ([*ioValue integerValue] < 1 ) {
        *outError = [NSError errorWithDomain:@"domain" code:102 userInfo:[NSDictionary dictionaryWithObject:@"Invalid Quantity" forKey:NSLocalizedDescriptionKey]];
        return NO;
    }
    return YES;
}
+(int)domething:(InstructionMessageObject*)消息在ManagedObjectContext:(NSManagedObjectContext*)上下文错误:(NSError**)错误{
n错误*内部错误=零;
int timeStamp=[[NSDate date]timeIntervalSince1970];
NSManagedObject*newMessageObject=[NSEntityDescription insertNewObjectForEntityForName:@“CoreDataTable”在ManagedObjectContext:context中];
[newMessageObject setValue:message.productCode forKey:@“productCode”];
[newMessageObject setValue:message.quantity forKey:@“quantity”];
///////////////////////////////////////
//保存前需要在此处进行验证//
///////////////////////////////////////
if(![context save:&internalError]){
*误差=内部误差;
返回否;
}
返回YES;
}
-(BOOL)validateProductCode:(id*)ioValue错误:(N错误**)outError{
*外误差=零;
如果([*ioValue integerValue]<1){
*outError=[NSErrorWithDomain:@“域”代码:101用户信息:[NSDictionary Dictionary WithObject:@“无效产品代码”forKey:NSLocalizedDescriptionKey]];
返回否;
}
返回YES;
}
-(BOOL)validateQuantity:(id*)ioValue错误:(n错误**)outError{
*外误差=零;
如果([*ioValue integerValue]<1){
*outError=[NSErrorWithDomain:@“域”代码:102用户信息:[NSDictionary Dictionary WithObject:@“无效数量”forKey:NSLocalizedDescriptionKey]];
返回否;
}
返回YES;
}
来自:

了解如何验证模型是很重要的 何时验证用户界面或控制器级别的决策 决策(例如,文本字段的值绑定可能具有 “立即验证”选项已启用)

而且:

没有什么可以阻止内存中的对象成为 暂时不一致的。验证约束是 仅在“保存”操作期间或根据请求由核心数据应用 (您可以根据需要直接调用验证方法)。 有时,在更改完成后立即验证更改可能很有用 并立即报告错误

请注意,当他们说“您可以直接调用验证方法”时,我不认为他们的意思是您应该实际调用特定于属性的验证方法,因为在这之后有一个注释:

重要提示:如果您实现了自定义验证方法,通常不应直接调用它们。相反,你应该打电话 validateValue:forKey:error:使用适当的键。这确保了 在托管对象模型中定义的任何约束也 应用


因此,只有在保存上下文时才会调用验证方法这一事实并不令人惊讶——这是核心数据进行验证的时候。这就是说,您可以更频繁地进行验证,如果您选择这样做,您应该通过调用
-validateValue:forKey:error:

来进行验证,据我所知,
保存:
操作应该会失败(并且不会向存储写入任何内容)如果任何验证方法报告错误。我想我已经找到了一个我喜欢的解决方案,但会导致新问题,我使用:[newMessageObject validateForInsert:&internalError]这将触发我正在处理的所有正确验证,但NSFetchedResultsController将其视为真正的记录插入和NSFetchedResultsChangeInsert。ViewController显示无效记录,即使它未保存。退出应用程序,记录已保存且显示正确。