0

私が次のことをしたとしましょう (foo は何らかのオブジェクトとして始まります):

[foo release];
// STUFF with foo   
[foo retain];

foo を再割り当てしない限り、これが終わっても同じ foo のままですよね? //STUFF 中に foo を失う危険はありませんか?

リリースに関する私の理解が正しいことを確認していると思います。foo を解放しても、すべてのハンドルがなくなるまで、実際には消えません。つまり、foo を //STUFF 内の他のオブジェクトに割り当てるか、または foo を //STUFF 内のスコープ外に移動する必要があります (おそらく新しい foo を作成する必要があります)。オブジェクトは削除されますよね?

動機のために編集:

これを行う理由は、次の switch ステートメントがあるとしましょう。

switch (test)
{
   case 1:
      foo = [A alloc];
      [foo inita];
      break;
   case 2:
      foo =  [B alloc];
      [foo initb];
      break;
   case 3: 
      [foo setupc];
      break;
   case 4:
      f = [D alloc];
      [foo initd];
      break;
}

スイッチの前に foo を解放し、最後に保持することは理にかなっています。ケース3を除いて。したがって、私が提案したことを安全に行うことができれば、コードがより簡単になるかもしれないと考えていました。

もちろん、各 alloc/init の周りに release/retain のペアを置くこともできますが、それは多くの複製されたコードです...

[foo autorelease] とその後の保持でうまくいくかもしれません。

4

4 に答える 4

3

いいえ、次のようになります。

この-releaseメソッドは保持カウントをデクリメントし、それが現在ゼロかどうかを確認します。保持カウントが 0 の場合、 を-release呼び出します[self dealloc]。これにより、オブジェクトの割り当てがすぐに解除されます。したがって、メッセージを送信-releaseする前に送信する-retainことは、あなたの例ではお勧めできず、アプリがクラッシュする可能性があります。

追加されたコメントに基づいて、コードの重複を回避しながら、必要なことを行うと思われるコードを記述する別の方法を次に示します。

Class class = Nil;

// Decide which class (if any) to use...
switch (test)
{
    case 1: class = [A class];  break;
    case 2: class = [B class];  break;
    case 3: class = foo == nil ? Nil : [C class]; break;
    case 4: class = [D class];  break;
}

// If a class was selected, create a new instance 
// and release the previous one...
if (class != Nil)
{
    [foo release];
    foo = [[class alloc] init];
}

-retain前に述べたように+alloc、保持カウントを 1 に設定するため、here は必要ないことに注意してください。

于 2010-03-05T22:18:18.680 に答える
3

そのコードの先頭で保持カウントがfooゼロになると、コードは消去されて動作しなくなります。autoreleaseそのようなことをしたい場合に使用します。releaseドキュメントによると、ガベージコレクションされた環境ではノーオペレーションです-多分それはあなたが考えていることですか?

于 2010-03-05T22:13:50.723 に答える
0

すべてreleaseのことは、すべてのオブジェクトが持つ参照カウンターをデクリメントすることです。

しかし、なぜあなたがそうしたいのか、あなたが示したようにreleaseしたいのかはわかりませretainん.

于 2010-03-05T22:14:20.847 に答える
0

はい、参照カウントされた(非GC)環境では、間違いなく「失う」危険があります。STUFF最初に の参照カウントを 0 に減らすと、割り当てが解除されます-releasefooこの場合に使い続けることはfoo、未定義の動作に足を踏み入れることであり、最終的にはほぼ確実に代償を払うことになります。つまり、ここにはドラゴンがいます。あなた(およびあなた呼び出す他のフレームワーク)がメモリを割り当てず、その間に参照STUFFれた割り当てられたインスタンスを上書きし、のメソッドが指すインスタンスが変更されない場合に機能する可能性がありますfoofoo-deallocfooインスタンス変数の参照を解放する以外の の状態と、それらの参照によって占有されていたメモリなどを破壊します。この場合、コードは割り当てが解除されていないかのように動作する可能性がありますが、それは運次第です。foo

ガベージ コレクション環境では、安全です。foothroughへの参照を保持しているSTUFFため、および-release-retainは GC 環境ではノーオペレーションであるため、foo引き続き有効です。

于 2010-03-05T22:41:31.573 に答える