0

누설 : 호출자가이 시점에서 소유 아닌 오브젝트의 참조 카운트 잘못된 감소량잘못된 감소는 할당 해제에서 I는 얻을에 '분석'으로

#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 

내가 출시하지 말아야한다는 의미입니까? 또한, 나는 'Profile'코드를 시도했는데 아무리 상관없이 [[[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

당신은 오히려 접근을 통해가는 것보다, 직접 바르를 해제해야합니다 : 당신은 접근의 반환 된 개체를 보유하고 있지 않습니다

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

, 당신이 그것을 해제해서는 안.

+0

감사 합니다만, 현재 메모리 누수가 해결되지 않았습니다. 그리고'viewDidUnload'에서'[foo release]'후에'self.foo = nil' 또는'foo = nil'을 사용해야합니까? –

+0

메모리 누수에 대한 내 잘못이 아니었다. http://stackoverflow.com/questions/2470744/avaudiorecorder-memory-leak –

관련 문제