8

私はまだ、私が取り組んでいるプロジェクトで見つけたこのコードを理解しようとしています。私が尋ねる前に、それを作成した人が会社を辞めた場所です。

これはコードです:

-(void)releaseMySelf{
    for (int i=myRetainCount; i>1; i--) {
        [self release];
    }
    [self autorelease];
}

私の知る限り、Objective-Cのメモリ管理モデルでは、最初のルールは、別のオブジェクトを割り当てるオブジェクトも、将来そのオブジェクトを解放する責任があるということです。それが私がこのコードの意味を理解していない理由です。何か意味はありますか?

4

4 に答える 4

17

著者は、メモリ管理を理解していないことを回避しようとしています。彼は、オブジェクトの保持カウントが保持ごとに増加すると想定しているため、そのリリース数を呼び出すことでオブジェクトを減少させようとします。おそらく彼は「将来それをリリースする責任もある」を実装していません。あなたの理解の一部。

ただし、ここ、ここここここなど、多くの回答を参照してください。

Appleのメモリ管理の概念を読んでください。

最初のリンクにはAppleからの引用が含まれています

保持カウントメソッドは、受信者に送信される保留中の自動解放メッセージを考慮しません。

重要:この方法は、通常、メモリ管理の問題をデバッグするのに価値がありません。任意の数のフレームワークオブジェクトがオブジェクトへの参照を保持するためにオブジェクトを保持している可能性があると同時に、自動解放プールがオブジェクトの任意の数の遅延リリースを保持している可能性があるため、これから有用な情報を取得できる可能性はほとんどありません。方法。従わなければならないメモリ管理の基本的なルールを理解するには、「メモリ管理ルール」をお読みください。メモリ管理の問題を診断するには、適切なツールを使用します。LLVM/ Clang Staticアナライザーは通常、プログラムを実行する前でもメモリ管理の問題を検出できます。Instrumentsアプリケーション(Instrumentsユーザーガイドを参照)のObject Allocインスツルメントは、オブジェクトの割り当てと破棄を追跡できます。Shark(Sharkユーザーガイドを参照)は、(プログラムの他の多くの側面の中で)メモリ割り当てもプロファイルします。

于 2011-12-16T11:23:44.270 に答える
7

すべての回答がmyRetainCountを[selfretainCount]と誤解しているように見えるので、このコードが記述された可能性がある理由を説明します。このコードが何らかの形でスレッドを生成しているか、クライアントに登録させている可能性があり、myRetainCountは事実上それらのクライアントの数。実際のOS保持数とは別に保持されます。ただし、各クライアントは独自のObjCスタイルの保持を取得する場合もあります。

したがって、この関数は、リクエストが中止された場合に呼び出される可能性があり、すべてのクライアントを一度に破棄し、その後、すべてのリリースを実行できます。これは良い設計ではありませんが、それがコードの動作方法である場合(そして、int myRetainCount = [self holdCount]、またはretain / releaseのオーバーライドを省略しなかった場合)、少なくともバグがあるとは限りません。

ただし、実際には何も改善せずに、責任の分散が悪いか、サークルの保持を回避しようとする不器用でハックニーの試みである可能性が非常に高くなります。

于 2011-12-16T18:07:51.577 に答える
3

これは、メモリを強制的に解放するための汚いハックです。プログラムの残りの部分が正しく記述されていれば、このようなことをする必要はありません。通常、保持とリリースのバランスが取れているため、保持カウントを確認する必要はありません。このコードの内容は、「誰が私を保持し、解放するのを忘れたのかわからない。記憶を解放したいだけだ。他の参照がこれからぶら下がっていてもかまわない」ということです。これはARCでコンパイルされません(奇妙なことに、ARCに切り替えると、作成者が回避しようとしていたエラーが修正される可能性があります)。

于 2011-12-16T11:25:21.200 に答える
2

コードの意味は、将来の結果がどうであろうと、オブジェクトの割り当てを今すぐ強制的に解除することです。(そして結果があります!)

他の誰かが実際にそのオブジェクトを「所有」しているという事実を考慮していないため、コードには致命的な欠陥があります。言い換えると、そのオブジェクトを「割り当て」たもの、および他の多くのものがそのオブジェクトを「保持」した可能性があります(NSArrayのようなデータ構造、自動解放プール、「保持」を行うだけのスタックフレーム上のコードなど) ); これらすべてのものがこのオブジェクトの所有権を共有します。オブジェクトが自殺した場合(releaseMySelfが行うことです)、これらの「所有者」は突然悪いメモリを指し示し、これは予期しない動作につながります。

うまくいけば、このように書かれたコードはただクラッシュするでしょう。おそらく、元の作者は他の場所でメモリをリークすることでこれらのクラッシュを回避しました。

于 2011-12-16T17:36:59.797 に答える