2011-06-30 21 views
9

私はずっとiPhoneでプログラミングしていて、メモリ管理に関して悪い経験をしています。私は次の方法がメモリを解放する良い方法であるかどうか疑問に思っていました。これはメモリを解放する良い方法ですか?

int count = [someObject retainCount]; 

for (int i = 0; i < count; i ++) 
{ 
[someObject release]; 
} 

この方法は、私が直面していたいくつかの状況(特にUIWebViews)で絶望の行為でした。変数のretainCountが0に減少し、それによって使用されているメモリが解放されます。メソッドは少し汚れていますが、それに関連するボトルネックはありますか?

+5

いいえ、メモリを解放するには良い方法ではありません。 – Sneakyness

+0

可能な限り早急にアップルのメモリ管理マニュアルをお読みください。メモリの管理方法が説明されています。決してこれをしないでください。 –

答えて

28

iOSフレームワークによって、オブジェクトを保持する可能性があるので、あなたがretainCountに頼るべきではありません、どのようなアップル下に読む

を約retainCountを言います。

重要:この方法は、典型的には、 のメモリ 管理の問題をデバッグするには値ではありません。同時に 自動解放プールが オブジェクトに延期リリースの任意の 数を保持することができる一方、フレームワークオブジェクトの任意の数 が、それへの参照 を保持するために オブジェクトを保持している可能性があるため、それはあなたのことはほとんどありません はこの メソッドから有益な情報を得ることができます。

メモリ管理の基本的な規則を理解するには、 "Memory Management Rules"と読みます。メモリ管理の問題を診断し、適切な工具を使用するには:

+3

あなた自身のオブジェクト*もオブジェクトを保持している可能性はもちろんですが、それは誰のオブジェクトであるかは関係ありません。何かがまだそれを保持している間にオブジェクトを刺したら、後でクラッシュするでしょう。 –

3

あなたはretainCountの値に依存しないでください。 alloccopyと同じくらい頻繁にリリースする必要があります。

編集:とnewretain

+0

また、「保持」する。 – beryllium

+0

と 'new'もあります:) – beryllium

+4

NARC ... new allocはコピーを保持します –

14

このコードは絶対no-goです。プログラミングミスを隠すだけでなく、非常に悪い方法でそれを行います。

適切なメモリ管理を学ぶしてください。代用品はありません。ここで

memory management programming guideです。それは複数回読む価値があります。他の人が述べたように

+1

これです。この1000倍! –

7

-retainCountは事実上無用です。 Objective-Cのメモリ管理/参照カウントを初めて使うときは、参照カウントがどのように機能するかを理解するのに役立つように - retainCountを試してみるのが魅力的かもしれませんが、現実には(おそらく)混乱する可能性があります。

あなたが掲示したコードは、周囲の状況に応じて、潜在的に危険であり、その可能性があります。someObjectが使用されています。また、あなたが期待していなかった他の状況に適用すると危険なこともあります。 @"a string"コンパイラ指令を使用して定数NSStringを作成します。これらの文字列は作成されず、決して解放されないように設計されています。

int main (int argc, const char * argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    NSString *string = @"theString"; 

    NSLog(@"retainCount == %lu", (unsigned long)[string retainCount]); 

    for (NSUInteger i = 0; i < [string retainCount]; i++) { 
     [string release]; 
    } 

    [pool drain]; 
    return 0; 
} 

この版画:

2011-06-30 08:40:16.287 retainCount[35505:a0f] retainCount == 1152921504606846975

をして、無限ループに入りますので、無限ループにつながる次の例のようにコードを適用します。

+0

Oooh、私は静的性格やシングルトンについては考えていませんでした。 – deanWombourne

+0

私は定数を解放しません。私はリリースが新しい、alloc、コピー、および保持のためだけに呼び出される必要があることを知っています。それはちょうどいくつかの状況では、いくつかのオブジェクトが私が予想した以上にカウントを保持していたことです。私が投稿した方法は、ほんのわずかのケースでの回避策でした。しかし、投稿された回答から、私はそれがなぜそのメソッドを使うのではなく保持されているのかを追跡するのが最善だと思う。 –

+2

カウントを保持する場合、「予想以上に」は「間違っている」という意味ではありません。あなたが責任を負うことを保証するだけで、あなたの新しい/ alloc/retain/copy呼び出しは全て対応する(自動)リリースとバランスが取れています。大丈夫だ。あなた以外のオブジェクトについては、NSVegasで何が起こるのか、NSVegasにとどまることを覚えておいてください。 :-) –

6

私は十分に強調することはできません!

はアクションであなたのコードのこの例を見てみましょう:

// Create an autoreleased object 
MyObject *myObject = [[[MyObject alloc] init] autorelease]; 

// Run your code to make it dealloc itself 
int count = [myObject retainCount]; 
for (int i = 0; i < count; i ++) 
    [myObject release]; 

あなたのコードはmyObjectがdeallocedことを強制します。

しかし、myObjectも自動解放プールに入れられました。プールがオブジェクトを解放するとすぐに、myObjectはもう存在しないため、アプリケーションがクラッシュする可能性があります。

ルールは単純です:init、new、またはcopyを使用するたびにreleaseを呼び出します。それ以外の場合はあなたの問題ではありません。

+0

この回答のベストビットは、サンプルコードにも問題があります。そのため、フレームワークを推測するのではなく、参照カウントルール(または自動参照カウントまたはガベージコレクション)に頼るべきです。 –

+0

私は混乱しています - stringWithStringを呼び出すと、自動解放プールにmyStringが追加されます。これは、将来、ある時点で解放しようとします。私は何が欠けていますか?(明らかに、私はOPのコードが持っている_only_という問題ではないことを明言しています。これは単なる例です) – deanWombourne

+0

'+ stringWithString:/ * NSConstantString * /'のインスタンスは単に定数を返します文字列なので、実際には静的オブジェクトを解放しようとしています。私が言ったように、重要な部分は間違っているということです。それが間違っていることを賢明にしようとすると、涙で終わるだけです。 –

関連する問題