2012-02-22 5 views
7

これは既存の投稿、What's the Point of (NSError**)error?と似ていますが、私の質問は少し異なります。私はダブルポインタがどのように動作するのか、これが一般的なiOS APIエラーパターンであることを理解しています。私の質問は、単一のポインタの周りに多い、なぜこのコードは動作しません:NSError *対NSError **

- (BOOL)someMethodWithError:(NSError *)error 
{ 
    ... 
    if(errorOccured) 
    { 
    NSError *e = [[[NSError alloc] initWithDomain:@"" code:1 userInfo:nil] autorelease]; 
    error = e; 
    return NO; 
    } 

    return YES; 
} 

は使用して実装:

NSError *error = nil; 
if(![someObj someMethodWithError:error]) 
{ 
    NSLog(@"Error: %@", [error localizedDescription]); 
} 

なぜメソッドの実装での割り当ては、ポインタを再割り当てしません。新しいNSErrorオブジェクト?

答えて

8

私は、ポインタを単なる整数と考えることが役立つことがわかりました。 (それはそれです)

あなたの例をintで見てください。

-(BOOL)someMethodWithError:(int)error 
{ 
    error =100; 
    return NO; 
} 

この整数は値渡しです。その関数がエラーと呼ばれた後は変更されません。

error = 123; 
    [self someMethodWithError:error]; 
    //error is = 123; 

ポインタは同じものです。値渡しです。

NSError * error; //this assigns this to a value in memory. 
    NSLog(@"%p",error); 
    [self someMethodWithError:error]; 
    NSLog(@"%p",error); // the value of error will not have changed. 

ポインタを変更したい場合は、そのポインタへのポインタを送信してそれを変更する必要があります。それは混乱していますが、自分自身に記憶の図を描き、それについて考えます。 :)

+1

優秀な説明madmik。ありがとうございました。ポインタが値渡しであることが今や分かります。 – Eric

+1

@ madmik3:ポインタを「単なる整数」と考えるのは危険です。ポインタはアドレスを含む変数です。 Cがポインタ上で '++'のような算術演算を使うことが許されているからといって、ポインタは整数のように振舞うわけではありません。たとえば、 '++'型の変数 'int'を使うと、その値に1を加えます。しかし、 '++'型の 'int *' *型の変数には、その値に4を加えたものになります。 – pje

+0

私はそれらを同じものと考えることを示唆しているわけではありませんが、渡す変数にどのように反応するかを見ると、時にはダブルポインタが必要な理由が明らかになります。これは例のためのものです。 :) – madmik3

0

これはC言語の仕組みです。あなたはこの質問と答えを見てみたいかもしれません: C double pointer、これは基本的には違った見方で同じものです。

0

井戸errorsomemethodWithErrorは、someMethodWithErrorが呼び出される場所のエラーのアドレスを含む別のポインタです。あなたがsomeMethodWithErrorerrorポインタに任意のオブジェクトを割り当てるときので、それはあなたのようなERROR2するために、任意の新しいオブジェクトを割り当てた場合、それは

NSError * error1 = obj1; 
NSError * error2 = error1; 

、その後のようなものだ

と呼ばれているところから、この方法の誤りポインタに反映されません

error2 = obj2; 

それはERROR1のポインタ値を変更しませんし、それはまだそれだ

3

をOBJ1を指すようになりますダブルポインターについて

なぜ新しい値が表示されないのですか?なぜなら、初期化したオブジェクトの内容をnilとして変更したことはないからです。これを行うには、nil値(ポインタへのポインタ)のコピーではなく、nil値が格納されていたメモリ位置への参照を使用する必要がありました。

これは、関数の出力のいくつかが入力引数のポインタを介して "返される" Cで行うのが本当に一般的なことです。

関連する問題