0

NSArray/ NSDictionary/NSSetとそれらの変更可能なサブクラスは、オブジェクト自体ではなく、オブジェクトへのポインターを追加しただけだと思いました。

では、コンテナーに追加した後に「単純な」オブジェクトを nil に設定した場合、配列 (コンテナー) にも参照 nil がないのはなぜですか?

コードは次のとおりです。

NSMutableArray *array = [[NSMutableArray alloc] init];

Simple *simple = [[Simple alloc] init];
[array addObject:simple];

//Array sends retain, lets release
[simple release], simple = nil;

NSLog(@"Simple = \"<Simple: %p>", simple);
NSLog(@"Array: %@", array);

[array release], array = nil;

出力は次のとおりです。

2011-02-16 20:00:03.149 Allocations[5433:207] Simple = <Simple: 0x0>
2011-02-16 20:00:03.150 Allocations[5433:207] Array: (
    <Simple: 0x4d3d4e0>
)
4

3 に答える 3

3

NSArray はオブジェクトへのポインタを追加します。変数への変更を追跡するために、配列は変数自体へのポインターを追加する必要があります (オブジェクトではなく、変数を nil に設定しているだけであることを思い出してください)。多くの変数がすべて同じオブジェクトを指している可能性があり、それらを再割り当てしても他の変数は変更されません。

注意: ポインタは魔法ではありません。これらは、値がメモリ アドレス (この場合はオブジェクトのメモリ アドレス) である通常の変数です。int同じオブジェクトへの 2 つのポインターは、値 を持つ2 つを超えて「リンク」されていません5。ポインターを変更しても、オブジェクトには影響しません。オブジェクトに影響を与えるには、オブジェクトを変更させるメッセージを送信するか (例[object setValue:6]) 、ポインタを逆参照してオブジェクトのメンバーに直接アクセスする必要があります (例object->value = 6)。

PS: オブジェクトのメンバーに直接アクセスしないでください。それは悪くて壊れやすく、バグが発生しやすいです。ポインタがどのように機能するかを説明するために、ここで言及しました。

于 2011-02-16T19:38:46.067 に答える
2

simple = nil を設定すると、そのポインタは何も指さなくなります。配列がまだポインタを持っているオブジェクトは削除されません。NSLog ステートメントの時点で、simple が指している Simple インスタンスの保持カウントは 1 になります。

シンプルに作成

  • simple => (単純なインスタンス: カウント 1 を保持)

配列に追加

  • simple => (単純なインスタンス: カウント 2 を保持)

  • [array objectAtIndex:0] => (単純なインスタンス: カウント 2 を保持)

シンプルなリリース

  • simple => (単純なインスタンス: カウント 1 を保持)

  • [array objectAtIndex:0] => (単純なインスタンス: カウント 1 を保持)

シンプルに設定= nil

  • シンプル => nil

  • [array objectAtIndex:0] => (単純なインスタンス: カウント 1 を保持)

リリースアレイ

  • (単純な例: カウント 0 を保持し、その後破棄)
于 2011-02-16T19:28:24.490 に答える
0

NSArray追加されたオブジェクトへのポインターのみが含まれていますが、それは問題ありません。simpleポインター自体を指しているのではなく、指しているSimpleオブジェクトをsimple指しています。したがって、あなたの例では、何simpleを指すかを変更した後も、配列は元のSimpleオブジェクトを指しています。

于 2011-02-16T19:24:50.027 に答える