だから、私はこれを見ました:
error:(NSError **)error
Apple doc's。なぜ2つの星なのか?意義は何ですか?
「二重星」は、ポインターへのポインターです。したがって、_NSError **
_はNSError
型のオブジェクトへのポインターへのポインターです。基本的に、関数からエラーオブジェクトを返すことができます。関数でNSError
オブジェクトへのポインターを作成し(_*myError
_と呼びます)、次のように実行できます。
_*error = myError;
_
そのエラーを呼び出し元に「返す」ために。
以下に投稿されたコメントへの返信:
Cでは関数パラメータが渡されるため、単純に_NSError *
_を使用することはできませんby value —つまり、関数に渡されると値がコピーになります。説明のために、このCコードのスニペットを考えてみましょう。
_void f(int x)
{
x = 4;
}
void g(void)
{
int y = 10;
f(y);
printf("%d\n", y); // Will output "10"
}
_
f()
でのx
の再割り当ては、f()
の外側の引数の値に影響しません(たとえば、g()
で)。
同様に、ポインターが関数に渡されると、その値がコピーされ、再割り当ては関数外の値に影響しません。
_void f(int *x)
{
x = 10;
}
void g(void)
{
int y = 10;
int *z = &y;
printf("%p\n", z); // Will print the value of z, which is the address of y
f(z);
printf("%p\n", z); // The value of z has not changed!
}
_
もちろん、z
が指す値をかなり簡単に変更できることはわかっています。
_void f(int *x)
{
*x = 20;
}
void g(void)
{
int y = 10;
int *z = &y;
printf("%d\n", y); // Will print "10"
f(z);
printf("%d\n", y); // Will print "20"
}
_
したがって、_NSError *
_が指すものの値を変更するには、ポインターにポインターを渡す必要もあります。
Cでは、すべてが値渡しされます。何かの値を変更したい場合は、そのアドレスを渡します(メモリアドレスの値を渡します)。ポインターが指す場所を変更する場合は、ポインターのアドレスを渡します。
Cでは、二重星はポインターへのポインターです。これにはいくつかの理由があります。 1つ目は、ポインターがポインターの配列を指す場合があることです。もう1つの理由は、関数にポインターを渡すことです。この場合、関数はポインターを変更します(他の言語の「出力」パラメーターに似ています)。
ダブルスター(**)表記は、クラス内の変数の初期化に固有のものではありません。これは、単にオブジェクトへの二重間接参照です。
float myFloat; // an object
float *myFloatPtr; // a pointer to an object
float **myFloatPtrPtr; // a pointer to a pointer to an object
myFloat = 123.456; // initialize an object
myFloatPtr = &myFloat; // initialize a pointer to an object
myFloatPtrPtr = myFloatPtr; // initialize a pointer to a pointer to an object
myFloat; // refer to an object
*myFloatPtr; // refer to an object through a pointer
**myFloatPtrPtr; // refer to an object through a pointer to a pointer
*myFloatPtrPtr; // refer to the value of the pointer to the object
ダブルポインター表記は、呼び出し元が関数呼び出しによって自身のポインターの1つを変更する必要がある場合に使用されるため、オブジェクトのアドレスではなく、ポインターのアドレスが関数に渡されます。
例として、リンクリストの使用があります。呼び出し元は、最初のノードへのポインターを維持します。呼び出し元は、検索、追加、および削除する関数を呼び出します。これらの操作に最初のノードの追加または削除が含まれる場合、呼び出し元のポインターは変更する必要があり、ノードの.nextポインターではなく、変更するにはポインターのアドレスが必要です。
Cのようなものであれば**
は、ポインターへのポインターを意味します。