ここで「error:&error」が使用されるのはなぜですか(objective-c)
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
とにかく、objective-cのオブジェクトは事実上参照渡しではないでしょうか?
ここで「error:&error」が使用されるのはなぜですか(objective-c)
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
とにかく、objective-cのオブジェクトは事実上参照渡しではないでしょうか?
の引数の型は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
であるため、運が悪いことになります。つまり、一度作成するとプロパティを変更できないため、関数は呼び出し元のコードで作成したインスタンスのまたはを変更できなくなります。NSError
domain
userInfo
NSError
- (NSArray*)executeFetchRequest:(Request *)request error:(NSError*)error {
...
error.domain = ... // not allowed!
error.userInfo = ... // not allowed!
}
これは事実上、別の戻り値です。操作の戻り値がある場合、Cocoaの慣例により、エラーは支配的ではありません。エラーが発生した場合、このoutパラメーターによってエラーが返される場合があります。
の場合、は変更可能なタイプではないNSError
ため、このように機能します。そのフィールドは初期化時に設定され、変更されることはありません。したがって、通常どおりにパスしてエラーコードを設定することはできません。NSError
NSError