2009-08-11 8 views
1

私はXML文字列を解析しており、メモリリークがあります。私はこのコードが漏れている知っているが、修正が何であるかわからない。このようなiPhoneのメモリリークObj Cコード

http://pastie.org/580694

コードは、根本的な欠陥であると表示されます。

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)value{ 
    if ([currentElement isEqualToString:@"problem_id"]){ 
     currentProblem.problemId = [[value copy] intValue]; 
    } else if ([currentElement isEqualToString:@"rule_instance_id"]){ 
     currentProblem.ruleInstanceId = [value copy]; 
    } else if ([currentElement isEqualToString:@"description"]){ 
     currentProblem.desc = [value copy]; 
    } else if ([currentElement isEqualToString:@"name"]){ 
     currentProblem.name = [value copy]; 

ではなく、私はつかんで対処すべきかどうかはわかり見つかったキャラクターとそれらを保持/解放する。

感謝Problemクラスの定義では

答えて

1

は、あなたのための財産のメモリ管理とコンパイラの契約をしてみましょう:

  • @property (retain) NSString *desc;で文字列プロパティを定義します。これにより、クラスが保持する文字列値の参照カウントがインクリメントされます(後で別の値が格納された場合は減分されます)。
  • intプロパティを@property (assign) int problemIdで定義します。照会対象から照会をコピーする必要はありません。

dealloc:の方法では、保持されているすべてのプロパティを必ず解除してください。 [desc release]

最後にcurrentProblemのプロパティに割り当てる前にvalueをコピーする必要はありません。 currentProblem.desc = valueは正しいことを行います。 [value copy]をそのまま残しておけば、それは漏れ続けます。問題のコードについては、それは場所のカップルで漏れた

:コピーが解放されることはありませんよう

  • [[value copy] intValue]は毎回parser:foundCharacters:をリークは、と呼ばれています。
  • の現在の実装では解放されないため、currentProblemがリリースされたときに、文字列メンバーcurrentProblemがリークします。
+0

私があなたの場合は、文字列に 'retain'の代わりに' copy'を使用します.-可変NSString'サブクラスがあります。 –

+0

ああ、良い点。ソリューションの残りの部分を保持する必要があります。文字列が変更可能である必要がない場合は、NSString + retainがより効率的になります。 –

1

currentProblem.problemId = ...は、[currentProblem setProblemId:...]に相当します。ほとんどの場合、problemIdにretainまたはcopyのセッターがあるとほぼ確実に宣言しているので、setProblemId:は渡されたオブジェクトを保持します。これは正常で良いことです。

currentProblem.desc = [value copy]; 

-copy返された値を保持し、その後、あなたがセッターで再びそれを保持されることを意味し、three magic wordsの一つです。だからあなたは二重に縛っている。メモリーリーク。

valueはNSStringですので、変更できません。それをコピーする理由はありません。多くのポインタは、不変オブジェクトを安全に共有できます。

この場合
currentProblem.problemId = [[value copy] intValue]; 

、problemIdは明らかに割り当て財産である(あるいはあなたがすぐにクラッシュする)、あなたはまだ呼んでいる:この行は少し異なっている

currentProblem.desc = value; 

:このコードは、する必要があります-copyvalueに変更すると、保持カウントが1増加して漏れます。このコードは、次のようにする必要があります。

currentProblem.problemId = [value intValue]; 

つまり、ここでオブジェクトをコピーするのをやめ、メモリリークがなくなります。コピーはObjCではいくぶん稀です。

+0

+1スポットをオンにして、コピーコマンドとメモリリークを取り除いてください。あなたがここでコピーコマンドを使用したという事実は、さらに多くのオブジェクトを "取得"する必要があることを示しています... – h4xxr

関連する問題