ITunes Uでスタンフォード大学のiPhoneコースを試してみましたが、ポインタについて少し混乱しています。最初の課題で、私はこのようなことをしてみました
NSString *processName = [[NSProcessInfo processInfo] processName];
NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];
エラーを生成しましたが、盲目的にいじり回した後、NSInteger行の*が問題の原因であることがわかりました。
だから何が起こっているのか私は明らかに理解していません。私はそれがどのように機能するかを説明します、そしておそらく誰かが欠陥を指摘するのに十分親切でしょう。
Web開発とは異なり、私は今、メモリについて、Web開発よりももっと心配する必要があります。したがって、変数を作成すると、どこかにメモリが割り当てられます(RAMと思います)。変数を渡す代わりに、メモリのそのビットへのポインタを渡します。ポインタは、変数名の前に*を付けることによって宣言されます。
私が正しいと仮定すると、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ビット整数です。
もちろん、あなたはcanをNSInteger
をポインタとして渡しますが、ほとんどの関数は単にNSInteger
として引数を取り、それへのポインタではありません。
一方、オブジェクトはポインタとしてのみ他の関数に渡すことができます。これは、オブジェクトに動的に割り当てられたメモリがあり、スタックで宣言できないためです。 int
またはlong
には固定量のメモリが割り当てられているため、これは問題ではありません。
*
は「ポインタ」を意味します。オブジェクト変数はオブジェクトへのポインタを保持するため、*
;があります。 NSInteger変数はNSIntegerへのポインタではなくNSIntegerを保持するため、*
はありません。その変数に*
を置くと、ポインター変数に整数を入れるため、少なくとも警告が表示されます。
NSIntegerは、int、AFAIKの単なる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