NSIntegerを*で宣言しないのはなぜですか
-
06-07-2019 - |
質問
スタンフォード大学のiTunes UのiPhoneコースを試してみましたが、ポインターについて少し混乱しています。最初の課題では、このようなことを試みました
NSString *processName = [[NSProcessInfo processInfo] processName];
NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];
エラーを生成しましたが、盲目的にいじくり回した後、NSInteger行の*が問題の原因であることを発見しました。
だから私は明らかに何が起こっているのか理解していない。私はそれがどのように機能するかを説明し、おそらく誰かが欠陥を指摘するのに十分親切になるでしょう。
ウェブ開発とは異なり、私は今必要です Web開発よりも、メモリについて心配する必要があります。だから私が 変数を作成し、割り当てられます メモリのビット(RAM I 想定)。渡す代わりに 変数の周りに、私はへのポインタを渡します メモリのそのビット。そして ポインタは、 *付きの変数名
私が正しいと仮定した場合、NSIntegerでそれをする必要がないのはなぜだろうか?
解決
NSInteger
はプリミティブ型です。つまり、スタックにローカルに保存できます。アクセスするためにポインターを使用する必要はありませんが、必要に応じて使用できます。行:
NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];
は、アドレスではなく実際の変数を返します。これを修正するには、 *
を削除する必要があります:
NSInteger processID = [[NSProcessInfo processInfo] processIdentifier];
本当に必要な場合は、 NSInteger
へのポインターを使用できます。
NSInteger *pointerToProcessID = &processID;
アンパサンドは演算子のアドレスです。変数内の整数ではなく、メモリ内の変数のアドレスに等しい NSInteger
へのポインターを設定します。
他のヒント
*
で NSInteger
を宣言しないのは、オブジェクトではないためです。 NSIntegerは、単に int
または long
:
#if __LP64__
typedef long NSInteger;
#else
typedef int NSInteger;
endif
32ビットアプリケーションで使用されている場合は32ビット整数であり、64ビットアプリケーションで構築されている場合は64ビット整数です。
もちろん、 NSInteger をポインターとして 渡すことができますが、ほとんどの関数は単に引数を NSInteger
として受け取り、それ。
オブジェクトは、ポインタとして他の関数にのみ渡すことができます。これは、オブジェクトにメモリが動的に割り当てられているため、スタックで宣言できないためです。 int
または long
には固定量のメモリが割り当てられているため、これは問題ではありません。
*
は“ pointer”を意味します。オブジェクト変数はオブジェクトへのポインターを保持するため、 *
があります。 NSInteger変数はNSIntegerへのポインターではなくNSIntegerを保持するため、 *
はありません。その変数に *
を置くと、ポインター変数に整数を入れているため、少なくとも警告が表示されます。
NSIntegerはintのtypedefであるだけです。
ポインターの使用
NSInteger integer1 = 1;
NSLog(@"1. integer1:%ld &integer1:%p", integer1, &integer1);
//1. integer1:1 &integer1:0x7ffee59e8a98
NSInteger *integer2 = &integer1;
NSLog(@"2. integer2:%p &integer2:%p *integer2:%ld", integer2, &integer2, *integer2);
//2. integer2:0x7ffee59e8a98 &integer2:0x7ffee59e8a90 *integer2:1
*integer2 = 2;
NSLog(@"3. integer2:%p &integer2:%p *integer2:%ld \t integer1:%ld &integer1:%p", integer2, &integer2, *integer2, integer1, &integer1);
//3. integer2:0x7ffee59e8a98 &integer2:0x7ffee59e8a90 *integer2:2 integer1:2 &integer1:0x7ffee59e8a98