7

Cocoa Bindings で私が常に悩まされてきた問題の 1 つは、エラーの表示です。たとえば、ユーザーがフォーマッタが接続されたテキスト フィールドに間違った値を入力した場合などです。通常、私はwillPresentError:レスポンダー チェーンのどこかをオーバーライドしますが、私の問題は、Bindings システムによって作成された NSError オブジェクトに、何が失敗したか、またはカスタマイズしたいエラーであるかどうかを判断するのに十分な情報が含まれていないことです。式からバインディングを完全に削除して、検証の問題が発生したときに独自のエラーを作成することもできますが、そうすると便利なものを捨ててしまうような気がします。

NSControl デリゲート メソッドを実装し、失敗したコントロールをビュー コントローラーのインスタンス変数に格納することで、これを回避することができました。ロールアラウンドまでに非 nil である場合、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が、View Controller を呼び出したときには機能しないため、私にとっては部分的にしか役に立ちません。

私が見ることができる他の唯一のオプションは、方程式から NSFormatter を取り出し、validateValue:forKey:error:検証を処理するために Core Data マネージド オブジェクトを使用することです。これは、フォーマッタを使用する場合ほど意味がありませんが、少なくとも NSError オブジェクトを完全に制御できます。

エラー処理でこの種の切断が発生するには、何かが欠けているに違いないと感じています。助言がありますか?

4

1 に答える 1

4

式からバインディングを完全に削除して、検証の問題が発生したときに独自のエラーを作成することもできますが、そうすると便利なものを捨ててしまうような気がします。

を使用NSUnderlyingErrorKeyして、1 つのエラー (そのキーのオブジェクト) を別のエラー (userInfoそのキーを含むエラー) でラップできます。

私が見ることができる他の唯一のオプションは、方程式から NSFormatter を取り出し、検証を処理するために Core Data 管理オブジェクトで validateValue:forKey:error: を使用することです。これは、フォーマッタを使用する場合ほど意味がありませんが、少なくとも NSError オブジェクトを完全に制御できます。

これらは 2 つの別個のレベルであり、相互に排他的ではありません。フォーマッタの検証はビュー レイヤーにあります。キー値の検証 (この場合は管理対象オブジェクト内) はモデル層にあります。

問題の検証がビュー レイヤーで発生する必要がある場合は、NSFormatter クラスをサブクラス化し (まだ行っていない場合) getObjectValue:forString:errorDescription:、より具体的なエラーの説明を返すように実装します。(ただし、Bindings が実際にこのエラーの説明を使用しているかどうかはわかりません。確認する必要があります。)

検証がモデル レイヤーで行われる必要がある場合は、NSManagedObject サブクラスにvalidate<Key>:error:(の単一プロパティ バージョン) を実装します。validateValue:forKey:error:

一部の制約がモデル レイヤーにあり、他の制約がビュー レイヤーにある場合は、両方を実行します。アプリとチェックにとって意味がある場合は、フォーマッタにいくつかのチェックを実装し、モデルに他のチェックを自由に実装できます。

于 2009-05-23T19:39:01.570 に答える