0

Objective-cのメモリ管理についていくつか質問があります。

まあ言ってみれば:

NSString * test= [[NSString alloc] init ]
test=@"msg";
[object setStr1: test ]; // declared as: @property(copy, readwrite)
[object setStr2: test ]; // declared as: @property(retain, readwrite)
[object setStr3: test ]; // declared as: @property(assign, readwrite)

test=@"some other string"

sのコンテンツstr1のコピーがあると思います:含まれているメモリ(ヒープ)の1つのアドレスを指します。このアドレスは、が指しているアドレスと同じではありません。右?teststr1msgtest

str2について:
1。何を保存しますか?、同じアドレスを指していると思いますtestが、参照カウンターが2に増えますtest。2
。テストの内容を変更すると、str2には何がありますか?私はそれがまだ指していると思いますmsg

str3について:それは間違っていますよね?、どうしassignますか?

ありがとう。

ボーナス質問:

NSString * test= [[NSString alloc] init ]
test=@"msg";
test=@"something";

コンテンツを変更する前にテストをリリースする必要がありますか?

4

2 に答える 2

3

ここで取り上げるべき最も重要なこと: 代入演算子=は、オブジェクトを変更 (つまり、変更) することはありません。オブジェクトの変更は、オブジェクトにメッセージを送信する (たとえば、 に送信appendString:するNSMutableString) ことによってのみ行うことができます。代入演算子は、ポインターが以前とは異なるオブジェクトを指すようにするだけです。

したがって、次のように言うのは正しくありません。

(1) NSString * test = [[NSString alloc] init];
(2) test = @"msg";

行 (1) は NSString オブジェクトを作成し、testそれを指すように割り当てます。行 (2) は同じことを行います: 新しい、無関係な NSString オブジェクトを作成し、それtestを指すように代入します。行 (1) で作成された元の NSString には、それを指すものがなく、リークされています。

allocまた、文字列リテラルは必要ありません。@"..."構文を使用すると、コンパイラはこれを暗黙的に行います。一般に、使用する必要はほとんどありません[NSString alloc]( などのさまざまなinit*メソッドを使用する場合のみinitWithFormat:)。

  1. str1テスト文字列の個別のコピーを指します。(正誤表: Eiko によると、不変の場合、受信者は単にこれを「保持」として扱います。これは、正しく動作している場合、実質的な違いはありません。)
  2. str2test と同じ場所を指し、そこにあるオブジェクトの保持カウントがインクリメントされます。
  3. str3test と同じ場所を指しますが、保持カウントはインクリメントされません。

一般的に言えば、文字列は不変であるため、その内容を変更することはできません。ただし、NSString のサブクラスである NSMutableString のインスタンスに注意する必要がある場合があります。これが、文字列を保持する代わりにコピーすることを多くの人が推奨する理由です。これにより、文字列がプログラムの別の部分によって変更された場合でも、オブジェクトのコピーは影響を受けません。

于 2010-09-09T18:31:59.887 に答える
1

2 行目では、テストを新しいオブジェクトに再割り当てし、最初の行で作成したオブジェクトへの参照を失うため、既にメモリ リークが発生しています。

str1 に対するあなたの結論は間違っています。なぜなら、コピーは不変型に対して self を返すだけかもしれないからです (とにかく変更されないため、システムは一度だけそれらを保持するのに十分なほどスマートです)。

str2 は確かに同じオブジェクトを指し、保持カウントを増やすだけです。不変であるため、テストの内容を変更することはできません。それが NSMutableString である場合、はい、str2 もこの変更を示します。

assign for str3 は「アドレスをコピーする」だけなので、(str2 と同じ) 同じオブジェクトを指しますが、それを保持しないため、そのオブジェクトの所有権/関心を主張しません。他の場所で解放すると、str3 はデッド メモリを指します。

おまけ:私の紹介のように、はい、あなたは漏れます。@"msg" を割り当てると、@"msg" が新しいオブジェクトを作成するため、元のオブジェクトがリークされます。

于 2010-09-09T18:35:52.293 に答える