7

我在 Cocoa Bindings 中一直遇到的一件事是错误呈现,例如,当用户在附加了格式化程序的文本字段中键入错误值时。通常我会覆盖willPresentError:响应程序链中的某个位置,但我的问题是 Bindings 系统创建的 NSError 对象没有包含足够的信息来告诉我失败的原因,或者它是否是我有兴趣自定义的错误。当验证问题发生时,我可以完全从方程式中删除绑定并创建自己的错误,但我觉得我会以这种方式扔掉一些有用的东西。

我已经能够通过实现 NSControl 委托方法并将失败的控件存储在我的视图控制器中的实例变量中来解决这个问题。如果到时候它不是零willPresentError:,我知道什么无法验证。

- (BOOL)control:(NSControl *)control didFailToFormatString:(NSString *)string errorDescription:(NSString *)error;
{
    _errorSender = [control retain];
    return NO;
}

- (NSError *)willPresentError:(NSError *)error;
{
    if ( _errorSender != nil )
    {
        NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithDictionary:[error userInfo]];
        NSString *help = NSLocalizedString( @"Why are you always messing up? You are a terrible person.", @"" );

        [_errorSender release];
        _errorSender = nil;
        [userInfo setObject:help forKey:NSLocalizedRecoverySuggestionErrorKey];

        return [NSError errorWithDomain:[error domain] code:[error code] userInfo:userInfo];
    }

    return [super willPresentError:error];
}

这在第一响应者更改时有效,但在我调用commitEditing视图控制器时无效,所以它对我来说只是部分有用。

我能看到的唯一其他选择是将 NSFormatter 排除在外,并validateValue:forKey:error:在我的 Core Data 托管对象中使用来处理验证。这对我来说没有使用格式化程序那么有意义,但至少我可以完全控制 NSError 对象。

我觉得我必须遗漏一些东西才能与错误处理产生这种脱节。有什么建议么?

4

1 回答 1

4

当验证问题发生时,我可以完全从方程式中删除绑定并创建自己的错误,但我觉得我会以这种方式扔掉一些有用的东西。

您可以使用NSUnderlyingErrorKey将一个错误(该键的对象)包装在另一个错误(userInfo包含该键的错误)中。

我能看到的唯一其他选择是将 NSFormatter 排除在外,并在我的核心数据托管对象中使用 validateValue:forKey:error: 来处理验证。这对我来说没有使用格式化程序那么有意义,但至少我可以完全控制 NSError 对象。

这是两个独立的级别,它们并不相互排斥。格式化程序验证在视图层;键值验证(在这种情况下,在您的托管对象中)位于模型层。

如果有问题的验证应该发生在视图层,请将您的 NSFormatter 类子类化(如果您还没有)并实现getObjectValue:forString:errorDescription:以返回更具体的错误描述。(不过,我不知道 Bindings 是否真的使用了这个错误描述。你应该检查一下。)

如果验证应该发生在模型层,请在您的 NSManagedObject 子类中实现validate<Key>:error:(的单属性版本)。validateValue:forKey:error:

如果一些约束在模型层而其他约束在视图层,那么两者都做。如果这对您的应用程序和检查有意义,您可以自由地在格式化程序中实施一些检查并在模型中实施其他检查。

于 2009-05-23T19:39:01.570 回答