1

私は始めたばかりで、これに少し夢中になっています。根本的な誤解があるかもしれませんが、よろしくお願いします。

文字列値を NSString* (および、他の多くのオブジェクト型) に直接割り当てることができるのはなぜですか? 例えば、

NSString* s = @"こんにちは、世界!";

一方、次のコードは s2 s1 のポインター値に割り当てられると思います (したがって、偶然に s2 に文字列値を提供するだけです)。

NSString* s1 = @"こんにちは、世界!";

NSString* s2 = s1;

多くのオブジェクトでは、値を代入する (つまり、setter メソッドを使用する) プロパティ (別名インスタンス変数) を指定する必要はありませんか? オブジェクト自体がポインター値の割り当てのみを受け入れるべきではありませんか? または、NSString などのクラスは、上記の最初の例のようなコードを自動的に再解釈し、暗黙のセッターを使用して、示された文字列を暗黙のインスタンス変数に割り当てますか?

4

4 に答える 4

3

文字列値を NSString* (および、他の多くのオブジェクト型) に直接割り当てることができるのはなぜですか?

そのように見えるかもしれませんが、文字列の値を「直接」インスタンス変数に割り当てているわけではありません。実際には、文字列値のアドレスをインスタンス変数に割り当てています。さて、本当の問題は、次の型の式があるときに舞台裏で何が起こっているかです。

NSString * str = @"Hello World";

この式は、文字列リテラルの作成を表します。C (および C の厳密なスーパーセットである Objective-C) では、文字列リテラルは特別な処理を受けます。具体的には、次のことが起こります。

  1. コードがコンパイルされると、文字列 "Hello World" がプログラムのデータ セクションに作成されます。
  2. プログラムが実行されると、インスタンス変数「str」がヒープに割り当てられます。
  3. 「str」インスタンス変数は、実際の文字列「Hello World」が保存されている静的メモリの場所を指します。

最初の例と 2 番目の例の主な違いは、2 番目の例では、文字列変数のメモリが実行時にヒープに動的に割り当てられることです。どちらの場合も、変数「str」は動的に割り当てられた単なるポインターであることに注意してください。

于 2012-11-09T01:37:49.200 に答える
1

多かれ少なかれ後者。のような文字列リテラル@"Hello World!"は、Objective-Cでは特殊なケースとして扱われます。その構文で宣言された文字列は、パフォーマンスを向上させるために、コンパイル時に静的に割り当てられ、インスタンス化され、キャッシュされます。プログラマーの観点から[NSString stringWithString:@"Hello World!"]は、C文字列を受け取る呼び出しやコンストラクターと同じです。構文糖衣と考える必要があります。

FWIW、Objective-Cは最近、@プレフィックスの拡張を開始して、辞書と配列リテラルも宣言できるようにしました(例:@{ @"key" : @"value" }または。) @[ obj1, obj2, obj3 ]

于 2012-11-09T01:32:17.477 に答える
0

これはコンパイラーの機能であり、言語構成ではありません。この場合のコンパイラは、文字列リテラルを認識し、目的の結果を生成するためにいくつかのコードを挿入します。

@ ""は、基本的にNSStringの+stringWithUTF8Stringメソッドの省略形です。

ここから取ってください: @記号はobjective-cで何を表していますか?

于 2012-11-09T01:31:54.143 に答える
0
NSString *s1 = @"Hello, world!";

本質的に同等です

NSString *s1 = [NSString stringWithUTF8String:"Hello, world!"];

前者は、新しい NSString オブジェクトを静的に割り当てます (後者のように実行時にヒープに割り当てるのではなく)。

これらは単なるポインタであることに注意することが重要です。を行う場合NSString *s2 = s1、 と の両方が同じオブジェクトs1を参照します。s2

于 2012-11-09T01:33:10.367 に答える