0

をリーク:呼び出し側によって、この時点で所有されていないオブジェクトの参照カウントの 不正な減少を不正な減少はにdeallocで私が得る、「分析」で

#import <AVFoundation/AVFoundation.h> 
@interface XYZViewController : UIViewController 
@property (retain) AVAudioRecorder *recorder; 
@end 
@implementation XYZViewController 
@synthesize recorder; 
- (void) dealloc 
{ 
    [self.recorder release]; 
    [super dealloc]; 
} 
- (void) viewDidLoad 
{ 
    NSURL *url = [NSURL fileURLWithPath:@"/dev/null"]; 
    NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys: 
          [NSNumber numberWithFloat: 44100.0],     AVSampleRateKey, 
          [NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey, 
          [NSNumber numberWithInt: 1],       AVNumberOfChannelsKey, 
          [NSNumber numberWithInt: AVAudioQualityMax],   AVEncoderAudioQualityKey, 
          nil]; 
    NSError *error; 
    self.recorder = [[[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error] autorelease]; 
} 
@end 

私はそれを放つべきではないという意味ですか? また、私はコードを 'プロファイル'しようとしていて、何からでもメモリリークが[[[AVAudioRecorder alloc] initWithURL:url settings:settings error:&error] autorelease]から出ます。

答えて

1

ではなくプロパティのアクセッサメソッドによって返されるオブジェクトに-releaseを送る、nilにプロパティ自体を設定します。

- (void)dealloc { 
    self.recorder = nil; 
    [super dealloc]; 
} 

あなたは、ストレージのセマンティクスを指定したため、コンパイラは、正しいことを行うために知っているだろうプロパティ宣言。 retainセマンティクスで宣言されたプロパティを合成すると、次のアクセサメソッドを書くことを効果的に等価です:

- (AVAudioRecorder *)recorder { 
    return recorder; 
} 

- (void)setRecorder:(AVAudioRecorder *)newRecorder { 
    [newRecorder retain]; 
    [recorder release]; 
    recorder = newRecorder; 
} 

あなたはself.recorder = nil書くとき、コンパイラは[self setRecorder:nil]に変換します。したがって、このようにプロパティをnilに設定すると、メモリリークやポインタの不具合を回避し、定型化の回数を減らし、コードの意図をより明確に表現できます。

最後に、宣言されたプロパティに関するセクションを持つThe Objective-C Programming Languageを再読み込みすることは決してありません。 Advanced Memory Management Programming Guideがあります。これは、メモリ管理のさまざまなアプローチをすべて詳しく説明しています。

+0

したがって、 'self.foo = nil;'は '[foo release]よりも優れています。 foo = nil; '。私はdeallocとviewDidUnloadの両方でそれを使用します。ありがとうございました! –

+0

'-dealloc'(または' -init'の 'self.foo = bar;')で 'self.foo = nil;'を使うことに注意する唯一のことは、副作用がある '-setFoo:'のカスタム実装では、奇妙なバグが発生する可能性があります。 '-init'や' -dealloc'の文脈では、あなたのオブジェクトは無効または初期化されていない状態であるとみなされるので、 'self'にメッセージを送るときは注意が必要です。しかし、単純なプロパティを設定またはクリアする一般的なケースでは、ドット表記法を使用します。メモリ管理のバグは、副作用のバグよりも一般的です。 –

4

あなたはむしろアクセサを通過するよりも、直接IVARを解放する必要があります

- (void)dealloc 
{ 
    [recorder release]; 
    [super dealloc]; 
} 

あなたはそれを解放するべきではありませんので、あなたは、アクセサの返されたオブジェクトを所有していません。

+0

ありがとうございます。現在のケースではメモリリークは解決されません。 'viewDidUnload'では、' [foo release]の後に 'self.foo = nil'または' foo = nil'を使うべきですか?メモリリークのための –

+0

、それは明らかに私のせいではありません:http://stackoverflow.com/questions/2470744/avaudiorecorder-memory-leak –

関連する問題