3

私はObjective-Cの初心者です。可変性/不変性の双子の概念に苦労しています。私は、Programming in Objective-C 4th Edition という本を読んでいます。NSString第15章では、不変であると述べられているクラスについて話します。次に、本はそれと矛盾するように見える例を提供します。

NSString *str1 = @"this is string A";
NSString *str2 = @"this is string B";

str2 = [str1 stringByAppendingString:str2];

NSString *res; 

res = [str1 substringToIndex:3];
res = [str1 substringFromIndex:5];
res = [[str1 substringFromIndex:8]substringToIndex:6];
res = [str1 substringWithRange:NSMakeRange(8, 6)];

'res' は不変オブジェクトへのポインターですが、その値は何度か変更されています。私はポイントを完全に見逃していると思います。どんなアドバイスも、ありがたく受け取った。

4

3 に答える 3

4

次の行で:

NSString *str2 = @"this is string B";
str2 = [str1 stringByAppendingString:str2];

文字列 "this is string B" (変数 に格納されていた) の内容は変更せずstr2、変数str2が別の文字列 (メソッドによって生成された新しい文字列) を指すようにします。stringByAppendingString:

const char*ここでの違いは、C の と の間とまったく同じchar* constです。

  • NSString*どちらも、const char*内容を変更できない文字列 (Cocoa または C) へのポインタを示します。変数は引き続き別の文字列を指すことができますが、元の文字列はその内容を変更しません。
  • char* constこれは、変更可能な文字列への定数ポインターであるorのような文字列への定数ポインターとは異なりますNSMutableString* const。つまり、文字列自体の内容は変更できますが、変数/ポインターは常にメモリ内の同じアドレスを指します。

この例を調べてください:

NSString* str1 = @"A";
NSString* str2 = str1; // points to the same immutable string
NSString* str3 = [str1 stringByAppendingString:@"B"];
// Now str1 and str2 both point to the string "A" and str3 points to a new string "AB"
str2 = str3;
// Now str2 points to the same string as str3 (same memory address and all)
// So str1 points to string "A" and str2 and str3 both point to "B"

この例では、 str1 は変更されておらず、そのままであることに注意してください"A"。変異していません。これは、次の他の例とは異なります。

NSMutableString* str1 = [NSMutableString stringWithString:@"A"];
NSMutableString* str2 = str1; // points to the same mutable string
[str2 appendString:@"B"];
// Now str1 and str2 still both point to the same string, but
// this same string has been mutated and is now "AB"
// So the string that previously was "A" is now "AB" but is still as the same address in memory
// and both str1 and str2 points to this address so are BOTH equal to string "AB"

この 2 番目の例では、文字列が変更されているため、この文字列を指している変数str1との両方に "AB" が含まれています。str2

于 2012-10-19T15:09:59.220 に答える
3

文字列オブジェクトの内容は不変です。ポインターを取得して、他のオブジェクトを指すようにすることもできます。

NSString *s = @"string1";
s = @"string2"

これは、最初の文字列オブジェクトの内容を変更しません。新しい文字列オブジェクトを割り当てて、それを*s指すだけです。メモリには文字列オブジェクト "string1" があり (ARC を使用していない場合)、何も指していません (後で解放されます)。

これを試して:

NSString *s = @"string1";
NSLog(@"String object at address %p has content %@.", s, s);
s = @"string2";
NSLog(@"String object at address %p has content %@.", s, s);

Test[1819:303] String object at address 0x100002890 has content string1.
Test[1819:303] String object at address 0x1000028d0 has content string2.

ご覧のとおり、新しいインスタンスが別のアドレスに作成されました。

クラスの名前で始まるメソッド (stringWith...や などarrayWith...) は、通常、そのクラスの新しいインスタンスを返します。

これらの方法のいずれかを使用して、上記と同じテストを実行できます。

NSString *s = @"string1";
NSLog(@"String object at address %p ha content %@", s, s);
s = [s substringToIndex:3];
NSLog(@"String object at address %p ha content %@", s, s);

Test[1857:303] String object at address 0x1000028a0 ha content string1
Test[1857:303] String object at address 0x10012ab70 ha content str
于 2012-10-19T15:03:13.887 に答える
1

あなたがres指している内容を変えているのではなく、指している内容を変えているからです。

于 2012-10-19T15:02:59.857 に答える