2011-07-06 16 views
0

NSStringを使用するメモリ管理について、ほとんどすべての質問をここで読んでいますが、実際にはこの問題を解決することはできません。NSStringを使用したメモリリーク

@interface:

@property (nonatomic, retain) NSString *criticalTranscription; 

@implementation: のviewDidLoad:I値を変更すると

- (IBAction) changeText:(id)sender 
{ 
    if(transcriptionSelector.selectedSegmentIndex == 1) 
    [transcription setText:diplomaticTranscription]; 
    else 
    [transcription setText:criticalTranscription]; 
} 

:に連結IBActionと

criticalTranscription = [[NSString alloc] init]; 

NSArray *paragraphs = [doc valueForKeyPath:@"critical.text"]; 
for(int i = 0; i < [paragraphs count]; i++) 
{ 
    criticalTranscription = [criticalTranscription stringByAppendingString:[[paragraphs objectAtIndex:i] valueForKey:@"p"]]; 
    criticalTranscription = [criticalTranscription stringByAppendingString:@"\n\n"]; 
} 
[transcription setText:criticalTranscription]; 

@XIB A UISegmentedControl UISegmentControlの(最初のものの直後ロードは、他に何も実行しない)、私は)YES =(このエラーにNSZombieEnabledを実行します。

2011-07-07 01:10:43.639 Transcribe[404:707] *** -[CFString length]: message sent to deallocated instance 0x1189300 

私はバックトレースの該当するものを見ることができません。 NSZombieEnabled criticalTranscriptionがなければ、ランダムな配列やその他のものを指し示すだけです。変数やリリースはそれ以上使用されません。

私は疑わしいリークを起こさずに分析を実行しました。

問題が何ですか?あなたのループ

criticalTranscription = [criticalTranscription stringByAppendingString:[[paragraphs objectAtIndex:i] valueForKey:@"p"]]; 
criticalTranscription = [criticalTranscription stringByAppendingString:@"\n\n"]; 

のためにあなたが自動解放文字列オブジェクトにcriticalTranscriptionを設定し、それを維持していない、ので、燃える死さで

+0

'diplomaticTranscription'はどこで作成して設定しますか? – PengOne

答えて

3

問題は、自分が所有していない文字列の参照を上書きしてしまうことです。

// you own the empty string returned here 
criticalTranscription = [[NSString alloc] init]; 

NSArray *paragraphs = [doc valueForKeyPath:@"critical.text"]; 
for(int i = 0; i < [paragraphs count]; i++) 
{ 
    // immediately overwrite allocated instance (that you own) 
    criticalTranscription = [criticalTranscription stringByAppendingString:[[paragraphs objectAtIndex:i] valueForKey:@"p"]]; 
    criticalTranscription = [criticalTranscription stringByAppendingString:@"\n\n"]; 
} 

ただし、不要な文字列で自動解放プールを汚染するため、この方法は使用しないでください。代わりに、変更可能な文字列を使用して、単一の変更可能な文字列インスタンスに文字列を追加します。

また、プロパティの組み込みメモリ管理を利用するには、を使用する必要があります。criticalTranscriptionではなく、使用する必要があります。 self.がなければ、インスタンス変数を直接使用しています。

+0

Doh!すでに1時間をお探しですか?ありがとう! – Patrick

1

これを保持するか、@property(nonatomic, copy)NSString *criticalTranscription;のプロパティを使用し、ivarではなくプロパティを使用できます。

1

2つの問題:あなたはそれに割り当てる

  • あなたは、文字列
  • の最初のインスタンスが漏れている後続のすべての値は、最も簡単な方法があり、それを修正するには

を自動解放なっていますcriticalTranscriptionをNSMutableStringに変更します。そして、あなたが行うことができます:

criticalTranscription = [[NSMutableString alloc] init]; 

NSArray *paragraphs = [doc valueForKeyPath:@"critical.text"]; 
for(int i = 0; i < [paragraphs count]; i++) 
{ 
    [criticalTranscription appendString:[[paragraphs objectAtIndex:i] valueForKey:@"p"]]; 
    [criticalTranscription appendString:@"\n\n"]; 
} 
[transcription setText:criticalTranscription]; 

を...代わりに、

[criticalTranscription appendFormat:@"%@\n\n", [[paragraphs objectAtIndex:i] valueForKey:@"p"]]; 

はまた、あなたがあなたがあなたの-viewDidLoadの終わりまたはその中のいずれか、それで終わったらcriticalTranscriptionreleaseを呼び出す必要があることに注意してください対応する-viewDidUnload

関連する問題