8

ここで「error:&error」が使用されるのはなぜですか(objective-c)

NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];

とにかく、objective-cのオブジェクトは事実上参照渡しではないでしょうか?

4

2 に答える 2

22

の引数の型はerror:ですNSError**(つまり、オブジェクトへのポインタへのポインタ)。これにより、オブジェクトは必要に応じmocて新しいオブジェクトを割り当てて初期化できNSErrorます。これは、特にココアでは一般的なパターンです。

NSErrorのドキュメントには、このアプローチの動機が示されています。

アプリケーションは、 localizedDescriptionをオーバーライドすることにより、より適切にローカライズされたエラー文字列を提供するために、NSErrorのサブクラスを作成することを選択できます。

NSError**引数を渡すと、そのメソッドNSErrorは意味のあるサブクラスを返すことができます。を渡した場合NSError*、既存のオブジェクトを指定する必要があり、メソッドが渡したオブジェクトとは異なるNSErrorオブジェクトを返す方法はありません。

明確にするために、メソッドは次のようになります。

- (NSArray*)executeFetchRequest:(Request *)request error:(NSError**)error {
    ...
    if ((error != NULL) && (some_error_condition)) {
        *error = [[[SomeNSErrorSubclass alloc] init...] autorelease];
        return nil;
    }
}

これにより、次のように、呼び出し元のコードがNULLパラメーターerror:を渡すだけでエラーを無視できるようになることに注意してください。

NSArray *array = [moc executeFetchRequest:request error:NULL];

更新:(質問への回答):

NSError**引数の型を次の代わりに使用する必要がある理由は2つありますNSError*。1。変数のスコープ規則と2.NSErrorインスタンスは不変です。

理由#1:可変スコープルール

関数宣言が次のようになっていると仮定しましょう。

- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error;

そして、次のような関数を呼び出すことになりました。

NSError * error = nil;
[someArray executeFetchRequest:someRequest error:error];
if (error != nil) { /* handle error */ }

この方法で変数を渡すと、関数本体はその変数のを変更できなくなります(つまり、関数本体は既存の変数を置き換える新しい変数を作成できなくなります)。たとえば、次の変数の割り当ては、関数のローカルスコープにのみ存在します。呼び出し元のコードには引き続きが表示されますerror == nil

- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error {
    ...
    error = [[[NSError alloc] init...] autorelease];             // local only
    error = [[[SomeNSErrorSubclass alloc] init...] autorelease]; // local only
}

理由#2:NSErrorのインスタンスは不変です

同じ関数宣言を維持しますが、次のように関数を呼び出します。

NSError * error = [[[NSError alloc] init...] autorelease];
[someArray executeFetchRequest:someRequest error:error];
if (error != nil) { /* handle error */ }

まず、変数スコープのルールは、errorができないことを保証するnilため、if (error != nil) { ...条件は常にtrueになりますが、ブロック内の特定のエラー情報を確認したい場合でも、のインスタンスは不変ifであるため、運が悪いことになります。つまり、一度作成するとプロパティを変更できないため、関数は呼び出し元のコードで作成したインスタンスのまたはを変更できなくなります。NSErrordomainuserInfoNSError

- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error {
    ...
    error.domain = ...   // not allowed!
    error.userInfo = ... // not allowed!
}
于 2011-11-30T23:34:29.160 に答える
3

これは事実上、別の戻り値です。操作の戻り値がある場合、Cocoaの慣例により、エラーは支配的ではありません。エラーが発生した場合、このoutパラメーターによってエラーが返される場合があります。

の場合、は変更可能なタイプではないNSErrorため、このように機能します。そのフィールドは初期化時に設定され、変更されることはありません。したがって、通常どおりにパスしてエラーコードを設定することはできません。NSErrorNSError

于 2011-11-30T23:41:59.707 に答える