如果涉及绑定,如何覆盖NSError表示?

Mar*_*eau 7 error-handling cocoa core-data objective-c cocoa-bindings

我在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];
}
Run Code Online (Sandbox Code Playgroud)

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

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

我觉得我必须遗漏一些东西,因为这种与错误处理的脱节.有什么建议?

Pet*_*sey 4

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

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

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

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

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

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

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