1

初歩的な質問はこちら:

基本的なメモリ管理を理解しようとしています。セッターメソッドをオーバーライドしている場合、次は着信文字列のメモリ管理を適切に処理しますか?

- (void)setMyString:(NSString *)string
{
    if (_myString != string){
        [string retain];
        [_myString release];
        _myString = string;
    }
}

ここでの私の論理は、その if ステートメントに入るとすぐに、着信文字列の所有権を取得したいので、保持します。次に、_myString オブジェクトを解放します。次に、_myString オブジェクトを文字列オブジェクトに設定します。これが私の混乱の原因です。この時点で myString オブジェクトを保持する必要がありますか? または、文字列オブジェクトと等しく設定した結果、既に所有権を持っていますか?

ありがとう!

4

3 に答える 3

4

あなたが書いたことは、最後の声明を除いてreturn _myString正しいです。

文字列で保持を呼び出すと、そのインスタンスの参照カウントが 1 つ増えます。string の値を に代入しても実際のインスタンス (現在はと_myStringの両方が指している) は変更されないため、2 番目の保持は必要なく、正しくありません。string_myString

そうは言っても、あなたが持っているものは一種の冗長です。チェックの理由はif (_myString != string)、セッターが既に持っている同じオブジェクトで呼び出された場合、そのオブジェクトを保持する前に解放したくないからです。そのような状況では、プログラムはクラッシュします。解放すると、割り当てが解除されますが、参照を保持して使用し続ける (メッセージを送信する) ためです。オブジェクトは同じなので、関数への引数がインスタンス変数の現在の値と同じである場合は、単に何もしないことでこの問題を回避できます。ただし、インスタンス変数を解放する前に引数を保持することは、まったく同じことを達成する別の方法です。

したがって、次のいずれかを実行できます。

- (void)setMyString:(NSString *)string
{
    if (_myString != string) {
        [_myString release];
        _myString = [string retain];
    }
}

またはこれ:

- (void)setMyString:(NSString *)string
{
    [string retain];
    [_myString release];
    _myString = string;
}

私は最初のアプローチを好む傾向があります。なぜなら、値が同じであれば(非常にわずかに)速く、書き出すと少し簡単だからです。しかし、実際には、それは個人的な好み次第であり、元の質問のフォームも問題ありません。

于 2012-10-11T19:31:32.630 に答える
1

保持と解放はもう使用しないでください。ARCを使用するだけで、多くの手間が省けます。メモリリークに対処したり、多くの保持/解放を書いたりする必要はありません。

そして、iOS 4 で動作し、現在の iOS のバージョンは 6 であるため、ARC が新しくなった昨年よりも ARC を使用する方がよいでしょう。

于 2012-10-11T20:21:35.593 に答える