当涉及到绑定时,如何覆盖NSError表示?

有一件事我在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对象。

我觉得我必须错过某些东西,因为这种断开与错误处理有关。 有什么建议么?


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

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

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

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

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

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

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

链接地址: http://www.djcxy.com/p/42665.html

上一篇: How do I override NSError presentation when bindings is involved?

下一篇: Inheriting from a generic contract in WCF