2

これに関連するいくつかの質問がありました: Objective-C でのアスタリスクの使用法

NSArray 配列。ローカルスコープでは、スタックに「割り当てられた」オブジェクトになります。NSArray *配列; 通常はヒープから割り当てられた、メモリの塊に支えられたオブジェクトを示します。

スタックとヒープに何かが割り当てられていることをどのように知ることができますか? すべてのローカル変数はスタック上にあり、すべてのポインターはヒープ上にありますか?

オブジェクトへのポインターを逆参照していないため、オブジェクトへのポインターはメソッド実装自体の中で重要です。あなたが言う時...

4

4 に答える 4

9

スタックとヒープに何かが割り当てられていることをどのように知ることができますか? スタック上のすべてのローカル変数は…</p>

それは問題ではありません。スタックとヒープは実装の詳細です。C 言語と Objective-C 言語はそれらを認識していないため、通常、何かがスタック上にあるかヒープ上にあるかを気にする必要はありません。

Mac OS X では、ローカル変数はスタックにあります。しかし、ほとんどすべての目的において、これは重要ではありません。ご心配なく。

…そして、すべてのポインターはヒープ上にありますか?

いいえ。ポインタはメモリ アドレスです。それで全部です。

ポインター変数は、他の変数が可能な場所ならどこにでも配置できます。つまり、どこにでも配置できます (前述のように、気にする必要のない実装定義の制限に従います)。

詳細については、ポインターのチュートリアルを参照してください。

オブジェクトへのポインターを逆参照していないため、オブジェクトへのポインターはメソッド実装自体の中で重要です。あなたが言う時...

ポインタはメモリアドレスです。そのため、そのアドレスのメモリを参照します。ポインターの逆参照は、そのメモリにアクセスしています。

Cocoa オブジェクトが占有するメモリに直接アクセスすることは決してありません。メッセージを送信して、質問をしたり、物事を行うように指示したりするだけです。したがって、ポインターを逆参照することはありません。

「…オブジェクトへのポインタは、メソッド実装自体の中で重要です。」メソッドの実装では、オブジェクトが独自のポインターを必要とすることを意味します。オブジェクトへのポインターにメッセージを送信することのみが可能です (この詳細は通常省略されます)。何らかの方法でこれを実行した場合、メッセージの受信者 (つまり、メッセージを送信したオブジェクト) には独自のポインターがありません。

逆参照されたオブジェクトにメッセージを送信できるとします。オブジェクトへのポインターにメッセージを送信するのが標準であるため、おそらく、オブジェクトはそれ自体へのポインターを必要とするため、逆参照されたオブジェクトにメッセージを送信するという仮想の機能は役に立たなくなります。

それは役に立たないので、彼らはそれを完全に残しました。オブジェクトには独自のポインターが必要になるため (ポインターはオブジェクトのメソッド実装にとって重要です)、そのポインターにのみメッセージを送信できます。

于 2010-01-13T06:09:35.350 に答える
4

* は、C、C++、および Objective-C の逆参照演算子です。逆参照演算子と一般的なメモリ管理を理解することは、Objective-C よりもはるかに広範です。これは、C/C++/Objective-C 開発者にとって基本的なスキルです。詳細については、ネット上の多数のイントロ C チュートリアルを参照してください。

編集: c ポインターに関する任意のチュートリアルで十分です。このようなhttp://home.netcom.com/~tjensen/ptr/pointers.htm

于 2010-01-13T05:20:32.440 に答える
2

Cocoa では、スタック割り当てオブジェクトを使用することはありません。すべてのオブジェクトは * で始まり (タイプ "id" は実際には "SOME オブジェクトへのポインター" の別の言葉であることを思い出してください)、ヒープ上に作成されます。

あなたはいつもこれを持っています:

NSArray     *myArray;

そして決してこれ:

NSArray     myArray;

常にポインターを逆参照しているため、2 番目のチャンクは無視できます。

于 2010-01-13T05:24:59.577 に答える
2

これらの素朴なおもちゃの例がお役に立てば幸いです。

Cでは、関数で、

int x; // x is a variable of type int in stack
int *xp; // xp is a variable of type int * (pointer to int) in stack
int *xp2 = (int *) malloc(sizeof(int)); // xp2 is a variable in stack, it points to a memory location(size is of int) in heap
xp = &x; // xp can point to x
xp = xp2; // xp can also point to what xp2 points to
free(xp2); // now xp and xp2 point to a freed memory, BAD to use xp and xp2 now.
int **y; // y is a variable in stack, type is int **
y = (int **) malloc(sizeof(int *)); // allocate a piece of memory in heap, to hold a pointer to int(int *)
*y = (int *) malloc(sizeof(int)); // allocate a piece of memory in heap, to hold an int
**y = 100; // now we can use it
free(*y);
free(y);

C++ では、関数またはメンバー関数 (メソッド) で、

SomeClass a1; // a1 is an object of type SomeClass in stack
SomeClass *a2 = new SomeClass(); // a2 is a pointer(in stack) pointing to an object(of type SomeClass) located in heap
delete a2;

したがって、C++ では、オブジェクトはスタックまたはヒープに存在できます。

Java では、関数またはメソッドで、

SomeClass b1; // b1 is just a reference, no object exists yet
b1 = new SomeClass(); // in java, objects can only exist in heap
int x; // however, primitive types are in stack, 

Objective-C では、関数またはメソッドで、

SomeClass c1; // you can't do this.
SomeClass *c2 = [[SomeClass alloca] init]; // c1 is a pointer in stack, pointing to an object in heap
[c2 release];
于 2010-01-13T06:21:21.310 に答える