2009-08-29 6 views
6

AVAudioPlayer와 관련된 이상한 메모리 누수 문제가 발생했습니다. 마음에 드는 모든 것을 시도한 후에 도움이 필요합니다.AVAudioPlayer 메모리 누수

다음은 문제에 대한 간단한 설명입니다. 바로 뒤에 코드가 나타납니다. 무한 루프에서 플레이어를 초기화하고 사운드 트랙을 재생하기 시작합니다 (그리고 끝없는 반복 또는 한 번 재생해도 문제가 변경되지 않음). 음악을 시작한 후 몇 초 후에 다른 사운드 트랙으로 전환하므로 새 플레이어를 만들고 초기화 한 다음 재생중인 이전 플레이어를 릴리스 한 다음 새 플레이어를 설정하고 재생합니다.

그 시점 (새 Player - [Player play]를 호출 한 직후)에 메모리 누수가 발생합니다 (3.5Kb).

나는 시도 다음

  • 이전 플레이어를 중지하고 다음을 해제 - 플레이어가 바로 재생 명령 후 효과

  • 자료 - 재생을 시작하지 않았을

  • 이전 플레이어를 두 번 출시 - 충돌 발생

  • 메모리 누수는 생성 및 재생할 때 발생하지 않습니다. 첫 번째 플레이어! 또한

기준에는 '놀이'비동기이라고 말할 않으며, 그래서 아마, 왜 [플레이어 중지] 않았다 도움이 심판의 카운트가 1 씩 증가하지만,이 경우에는?

- (void) loadAndActivateAudioFunction { 
NSBundle  *mainBundle = [NSBundle mainBundle]; 
NSError   *error; 
NSURL   *audioURL = [NSURL fileURLWithPath:[mainBundle pathForResource: Name ofType: Type]]; 
AVAudioPlayer *player = [(AVAudioPlayer*) [AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error]; 

if (!player) { 
    DebugLog(@"Audio Load Error: no Player: %@", [error localizedDescription]); 
    DuringAudioPrep = false; 
    return; 
} 
[self lock]; 
[self setAudioPlayer: player]; 
[self ActivateAudioFunction]; 
[self unlock]; 

}

- (void) setAudioPlayer : (AVAudioPlayer *) player { 
if (Player) 
{ 
    if ([Player isPlaying] || Repeat) // The indication was off??? 
     [Player stop]; 
    [Player release]; 
} 
Player = player; 

}

- (void) ActivateAudioFunction { 
[Player setVolume: Volume]; 
[Player setNumberOfLoops: Repeat];  
[Player play]; 

DuringAudioPrep = false; 

}

을 :

감사합니다, 여기에

내가 그것을 사용하는 방법에 대한 코드의 일부입니다

답변

0

본인의 코드는 지금까지 본인에게 잘 보이기 때문에 문제의 원인이되는 코드가있을 수 있습니다.

나는 당신이 일종의 이상한 숙어를 사용하고 있다고 말할 것입니다. 실제로 쉽게 만들 수있는, 당신의 setAudioPlayer 방법에 올 때 당신은 "선수"개체를 유지, 이러한 방법으로

// new players will always be created autoreleased. 
    AVAudioPlayer *player = [[(AVAudioPlayer*) [AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error] autorelease]; 

- (void) setAudioPlayer : (AVAudioPlayer *) player 
{ 
    if (Player) 
    { 
     if ([Player isPlaying] || Repeat) // The indication was off??? 
      [Player stop]; 
     [Player release]; 
    } 
    Player = [player retain]; 
} 

: 오히려 생성에 유지하고 세트에 발표보다, 나는 이런 식으로 뭔가를 할 거라고 추적하기.

또한 실제 누설되는 AVAudioPlayer 개체인지 확인하십시오. 인 스트 루먼트가이를 확인할 수 있어야합니다.

+0

답해 주셔서 감사합니다. 예 - 인스트루먼트가있는 AVAudioPlayer인지 확인했습니다. 방법에 관해서 - 나는 실제로 다른 트랙을 저장하고 일치하는 이름으로 그리고 (동일한 트랙을 여러 번 다운로드하는 대신) 재생하지 않기 때문에 재사용하기 때문에 이것을 사용합니다. "Alloc"을 호출 한 후 호출자로부터 Player를 얻은 것을 알고 있기 때문에, 내가 잘못 이해하지 않는 한 이미 보존되었다는 것을 알고 있습니다. – Adi

7

다음은 메모리 누수없이 AVAudioPlayer를 만드는 방법입니다. See this page for explaination.

내 앱에서 AVAudioPlayer의 누출이 100 % 제거 된 것으로 확인되었습니다.프로젝트

+1

두 번째로 NSData * audioData를 입력해야한다고 생각합니다. line ... – SpaceDog

+0

이 코드는 정말 이상하다. alloc 대 init 호출을 나눌 이유가 없다. 보다 일반적인 접근법은 http://stackoverflow.com/questions/17603551/arc-forbids-autorelease/17604365#17604365를 참조하거나 [[[AVAudioPlayer alloc] initWithData : audioData error : NULL]과 같이 autorelease를 추가하면됩니다. autorelease ] – MoDJ

-2

봅니다 프로토콜 AVAudioPlayerDelegate 및 그 방법 audioPlayerDidFinishPlaying를 구현 : 성공적으로 : 다음 오디오 플레이어 오브젝트

예를 놓습니다.

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { 
    [player release]; // releases the player object 
} 
+0

'MediaPlayer.framework'? 'AVAudioPlayer'는'AVFoundation.framework'에 있고'MediaPlayer'는 필요 없습니다. 정교한 케어? –

2

에 MediaPlayer.framework를 추가

- (AVAudioPlayer *)audioPlayerWithContentsOfFile:(NSString *)path { 
    NSData *audioData = [NSData dataWithContentsOfFile:path]; 
    AVAudioPlayer *player = [AVAudioPlayer alloc]; 
    if([player initWithData:audioData error:NULL]) { 
     [player autorelease]; 
    } else { 
     [player release]; 
     player = nil; 
    } 
    return player; 
}