2

Cocoa / Obj-Cの初心者である私は、AaronHillegassによる「CocoaProgrammingfor Mac OS X」の本を読んでいますが、GCを使用してこのような理由をすべて回避する機会もあるという事実は別として、私はそうではありません。確かに私はそれらの保持のいくつかの理由を理解しています。

特に、例の1つでは、アーロンは優れたプログラミング手法として次のように示しています。

- (void) setFoo:(NSCalendarDate *)x
{
    [x retain];
    [foo release];
    foo = x;
}

メソッドの最初の行にxインスタンスを保持する理由がわかりません。

[x retain];

このインスタンスのスコープは、setメソッドだけですよね?メソッドスコープを終了するとき、xインスタンスはとにかく割り当てを解除する必要がありますか?さらに、次の方法でxをfooに割り当てる場合:

foo = x;

fooはとにかくx個のメモリセルを指しているので、ポイントされたオブジェクトの保持カウントをインクリメントします。これにより、メモリの割り当てが解除されないようにする必要があります。

それで、ポイントは何ですか?もちろん、何かが足りないと思いますが、正確にはわかりません。

ありがとう、ファブリツィオ

4

1 に答える 1

12

保持とは、このオブジェクトを保持する必要があることを意味します。割り当てを解除してはなりません。x保持されない場合、次のことが発生する可能性があります。

に割り当てるxのでfoofooNSCalendarDateがあるアドレスを指します。誰かがこのオブジェクトを解放または自動解放すると、保持カウントが最終的に0に下がり、オブジェクトの割り当てが解除されます。fooこれで、まだそのアドレスを指していますが、有効なオブジェクトはもうありません。しばらくして、新しいオブジェクトが作成され、たまたま古いNSCalendarDateオブジェクトと同じアドレスに配置されます。これfooで、まったく異なるオブジェクトを指すようになりました。

それを防ぐために、あなたはそれをする必要がありますretain。あなたは言う必要があります、まだオブジェクトの割り当てを解除しないでください、私はそれが必要です。使い終わったら、オブジェクトはもう必要ないreleaseということです。他に誰も必要としない場合は、今すぐクリーンアップできます。

次に、古典的な3つの部分からなる割り当てについて説明します。setFoo:あなたがこのように見えると考えてください:

- (void) setFoo:(NSCalendarDate *)x
{
    [foo release];
    [x retain];
    foo = x;
}

これは非常に悪い考えです。NSCalendarDateオブジェクトを保持しているのはオブジェクトだけであると考えてから、次のことを行うと考えてください[self setFoo:foo];。ばかげているように聞こえるかもしれませんが、このようなことが起こる可能性があります。フローは次のようになります。

  1. fooリリースされます。その保持カウントが0に低下し、オブジェクトの割り当てが解除される可能性があります。
  2. おっと、割り当て解除されたオブジェクトを保持してアクセスしようとしています。

これが、常に最初retainに新しいオブジェクト、次にrelease古いオブジェクトを使用する理由です。

Javaまたは.NETのバックグラウンドを使用している場合、型の変数にはオブジェクトのアドレスFoo *のみが含まれ、それ以上は含まれないことを理解することが非常に重要です。Javaまたは.NETでは、オブジェクトを指す変数は、必要に応じて、オブジェクトを自動的に「保持」します。Objective-Cではそうではありません(非GC環境)。型の変数を弱参照と見なすことができ、そのアドレスでそのオブジェクトがまだ必要かどうかをObjective-Cに明示的に伝える必要があります。Foo *

于 2011-06-02T10:31:30.327 に答える