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

时间:2009-05-23 18:51:41

标签: objective-c cocoa core-data error-handling 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];
}

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

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

我觉得我必须要错过一些与错误处理有这种脱节的东西。有什么建议吗?

1 个答案:

答案 0 :(得分:4)

  

我可以完全从等式中删除绑定并在验证问题发生时创建我自己的错误,但我觉得我会抛出一些有用的东西。

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

  

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

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

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

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

如果某些约束位于模型层而其他约束位于视图层,请同时执行这两个操作。如果对您的应用和支票有意义,您可以在格式化程序和模型中的其他检查中自由执行某些检查。