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

发布于 2024-07-22 07:12:08 字数 1432 浏览 5 评论 0原文

我在 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 对象。

我觉得我一定错过了一些东西,才会出现这种与错误处理的脱节。 有什么建议么?

One thing I've always had trouble with in Cocoa Bindings has been error presentation, for example when the user types the wrong value into a text field with a formatter attached. Normally I would override willPresentError: somewhere in the responder chain, but my problem is the NSError objects created by the Bindings system doesn't contain enough information for me to tell what failed, or if it's even an error I'm interested in customizing. I could completely remove bindings from the equation and create my own errors when validation problems occur, but I feel like I would be throwing out some useful stuff that way.

I've been able to get around this by implementing the NSControl delegate methods and storing the control that failed in an instance variable in my view controller. If it's non-nil by the time willPresentError: rolls around, I know what failed to validate.

- (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];
}

This works when the first responder changes, but not when I call commitEditing on the view controller, so it's only partially useful to me.

The only other option I can see is taking NSFormatter out of the equation, and using validateValue:forKey:error: in my Core Data managed objects to handle validation. This doesn't make as much sense to me as using a formatter, but at least I'd have full control over the NSError object.

I feel like I must be missing something for there to be this kind of disconnect with error handling. Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

︶ ̄淡然 2024-07-29 07:12:08

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

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

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

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

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

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

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

I could completely remove bindings from the equation and create my own errors when validation problems occur, but I feel like I would be throwing out some useful stuff that way.

You can use NSUnderlyingErrorKey to wrap one error (the object for that key) in another error (the one whose userInfo contains that key).

The only other option I can see is taking NSFormatter out of the equation, and using validateValue:forKey:error: in my Core Data managed objects to handle validation. This doesn't make as much sense to me as using a formatter, but at least I'd have full control over the NSError object.

These are two separate levels, and they aren't mutually exclusive. The formatter validation is at the view layer; key-value validation (in this case, in your managed objects) is at the model layer.

If the validation in question should happen at the view layer, subclass your NSFormatter class (if you haven't already) and implement getObjectValue:forString:errorDescription: to return a more specific error description. (I have no idea whether Bindings actually uses this error description, though. You should check.)

If the validation should happen at the model layer, implement validate<Key>:error: (the single-property version of validateValue:forKey:error:) in your NSManagedObject subclass.

If some of the constraints are at the model layer and others are at the view layer, do both. You're free to implement some checks in the formatter and other checks in the model, if that makes sense for your app and your checks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文