2009-08-29 21 views
6

मैं AVAudioPlayer से संबंधित कुछ अजीब स्मृति रिसाव समस्या पर फंस गया हूं और मुझे दिमाग में आने वाली हर चीज की कोशिश करने के बाद सहायता चाहिए।AVAudioPlayer मेमोरी लीक

यहां समस्या का संक्षिप्त विवरण दिया गया है - कोड ठीक बाद में दिखाई देता है। मैं अपने खिलाड़ी को आरंभ करता हूं और एक अंतहीन पाश में ध्वनि ट्रैक चलाने के लिए शुरू करता हूं (और अंतहीन लूप या एक बार खेलने में समस्या नहीं बदली)। संगीत शुरू होने के कई सेकंड बाद, मैं एक और ध्वनि ट्रैक पर स्विच करता हूं, इसलिए मैं एक नया खिलाड़ी बनाता हूं, इसे शुरू करता हूं, पुराना एक (जो खेल रहा है) जारी करता है और फिर नया स्थान सेट करता है और इसे चलाता है।

उस समय पर (नए खिलाड़ी को कॉल करने के ठीक बाद - [प्लेयर प्ले]) मुझे मेमोरी लीक (3.5 केबी) मिलती है।

मैंने कोशिश की है:

  • वर्ष खिलाड़ी बंद करो और फिर उसे छोड़ दें - कोई प्रभाव नहीं

  • रिलीज प्लेयर सही खेलने अनुदेश के बाद - खेलना शुरू नहीं किया था

  • पुराने खिलाड़ी को दो बार रिलीज़ करें - क्रैश

  • मेमोरी लीक तब नहीं होता जब मैं बना और खेलता हूं पहला खिलाड़ी!

इसके अलावा, संदर्भ में यह कहा गया है कि 'चलाएँ' पर async है और इसलिए शायद इसे 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

जहां तक ​​मैंने देखा है, आपका कोड मेरे लिए ठीक दिखता है, इसलिए शायद कहीं और कोड है जो समस्या पैदा कर रहा है।

मैं कहूंगा कि आप एक प्रकार का विषम मुहावरे का उपयोग कर रहे हैं। बल्कि बनाने पर बनाए रखने और सेट पर जारी की तुलना में, मैं इस तरह कुछ करना चाहते हैं:

// 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]; 
} 

इस तरह, आप केवल "खिलाड़ी" वस्तुओं को बनाए रखने के लिए जब वे वास्तव में अपने setAudioPlayer विधि में आते हैं, यह आसान बना सकता है जो नीचे ट्रैक करने के लिए।

इसके अलावा, यह सत्यापित करें कि यह वास्तव में एक AVAudioPlayer ऑब्जेक्ट है जो लीक हो रहा है। उपकरण आपके लिए यह सत्यापित करने में सक्षम होना चाहिए।

+0

उत्तर के लिए धन्यवाद। हाँ - मैंने सत्यापित किया है कि यह उपकरण के साथ AVAudioPlayer है। विधि के रूप में - मैं इसका उपयोग करता हूं क्योंकि मैं वास्तव में अलग-अलग ट्रैक सहेजता हूं और नाम मिलान करके उन्हें पुन: उपयोग करता हूं और यदि वे नहीं खेल रहे हैं (एक ही ट्रैक को कई बार डाउनलोड करने के बजाय)। चूंकि मुझे पता है कि मैं उस पर 'एलोक' करने के बाद कॉलर से प्लेयर प्राप्त करता हूं, मुझे पता है कि यह पहले से ही बरकरार है (जब तक मुझे यह गलत न हो?) – Adi

7

मेमोरी लीक के बिना AVAudioPlayer बनाने का तरीका यहां दिया गया है। See this page for explaination

मैंने अपने ऐप में पुष्टि की है कि इसने मेरे AVAudioPlayer को 100% हटा दिया है।

- (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; 
} 
+1

मुझे लगता है कि इसे दूसरी बार एनएसडीएटा * ऑडियोडेटा टाइप किया जाना चाहिए लाइन ... – SpaceDog

+0

यह कोड वास्तव में अजीब है, आवंटन बनाम इनिट कॉल को विभाजित करने का कोई कारण नहीं है। एक बेहतर सामान्य दृष्टिकोण के लिए, http://stackoverflow.com/questions/17603551/arc-forbids-autorelease/17604365#17604365 देखें या आप [[[AVAudioPlayer alloc] initWithData में ऑटोरेलीज़ जोड़ सकते हैं: ऑडियोडेटा त्रुटि: NULL] autorelease ] – MoDJ

-2

अपनी परियोजना

+0

'मीडियाप्लेयर.फ्रेमवर्क '? 'AVAudioPlayer'' AVFoundation.framework' में स्थित है और 'MediaPlayer' की आवश्यकता नहीं होनी चाहिए। विस्तृत करने के लिए परवाह? –

2

को MediaPlayer.framework जोड़ने का प्रयास करें लागू प्रोटोकॉल AVAudioPlayerDelegate और उसके विधि audioPlayerDidFinishPlaying: सफलतापूर्वक: तो ऑडियो प्लेयर वस्तु

जैसे छोड़ें।

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { 
    [player release]; // releases the player object 
} 
संबंधित मुद्दे