2010-02-04 38 views
0

几分钟前,我发布了一个更长的问题,因为它通常会在我发布后立即发布,所以我删除了它,因为大多数帖子都是无关紧要的。然后我回到谷歌。iPhone:AVAudioPlayer/NSURL内存管理

原来,我的问题几乎与本文中描述的完全相同,未从6月份回复。 http://www.iphonedevsdk.com/forum/iphone-sdk-development/20975-avaudioplayer-nsurl-memory-management.html

总结:我使用AVAudioPlayer并使用audioPlayerDidFinishPlaying:successfully:delegate方法发布它。初始化播放器后,需要释放其关联的NSURL对象,否则会泄漏。但是当初始化播放器后,当它释放它时,它已经释放,因为它已经被释放。奇怪的是,它并不总是第一次崩溃,大部分时间它在第二个声音播放后崩溃。有时(很少)它会允许少数玩家或玩家在崩溃之前被分配/释放(我在释放后重新使用指针)。任何帮助?

代码片段:(soundKeyUp是AVAudioPlayer *类变量,因此在这里没有申报)

NSString *soundKeyUpPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"soundKeyUp%d", key.tag % 5] ofType:@"wav"]; 
    NSURL *soundKeyUpURL = [[NSURL alloc] initFileURLWithPath:soundKeyUpPath]; 
    soundKeyUp = [[AVAudioPlayer alloc] initWithContentsOfURL:soundKeyUpURL error:nil]; 
    if(soundKeyUp) { 
     [soundKeyUp setDelegate:self]; 
     [soundKeyUp play]; 
    } 
    else { 
     [soundKeyUp release]; 
     soundKeyUp = nil; 
    } 

    [soundKeyUpPath release]; 
    [soundKeyUpURL release]; 

回应史蒂夫金斯: 它的巧妙之处在于它不会在同一时间每次崩溃时间,如前所述。它几乎总是第一次正确发布(至少它不会崩溃或泄漏),但通常在第二次分配/释放播放器和URL后,它在发布URL时崩溃。有时候,它在崩溃之前会超过3,4,5次,但它总是会发生。

回答

1

创建播放器时释放URL。我在我的应用程序中这样做,它的功能很好。没有泄漏,崩溃等

AVAudioPlayer *newPlayer = 
     [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL 
               error: nil]; 
     [fileURL release]; 

永远不会释放其他对象包含的对象。那是他们的工作,而不是你的工作。

编辑:如果您的网址仍在泄漏,您需要查看您在创建时的操作。它应该是这样的:

NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: [self path]]; 

遵循可可规则的所有权,使用alloc方法意味着你拥有它,所以你释放它。

+0

我已经用我的实际代码和直接响应更新了我的帖子,因为我无法将它放入评论框中。当我创建播放器时,我*做*发布URL,我对委托方法所作的编辑只是一个测试,看看程序中当时发生了什么。 对,我知道不会释放其他对象包含的对象,但1)我没有意识到在查看它之前,AVAudioPlayer在初始化后将NSURL保留为属性,所以我很好奇AVAudioPlayer是否处理/如何处理它; 2)试图破坏事物是学习它们如何工作的好方法。 – 2010-02-05 01:25:16

+0

同意。你永远不应该使用任何看起来像这样的东西:'[[something methodName] release]'。这只是疯狂的内存错误等待发生。 – 2010-02-05 01:25:49

+0

else { [soundKeyUp release]; soundKeyUp = nil; } 你当然不需要这个。如果对象为零,则不需要释放它。 你确实需要在dealloc中释放它。我会使用这个ivar的retain属性,以便在dealloc中你可以简单地使用self.soundKeyUp = nil。 @property(nonatomic,retain)AVAudioPlayer * soundKeyUp; 然后在执行@synthesize soundKeyUp。 then self.soundKeyUp = [[AVAudioPlayer alloc] ....等 你可能犯了一些错误,使得它很难调试。小心了解每个分配的每个阶段。 – 2010-02-17 20:12:37

0
- (IBAction) playaction { 

     NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:@"songname" ofType:@"mp3"]; 
     NSURL *newURL = [[NSURL alloc] initFileURLWithPath: soundFilePath]; 
     self.soundFileURL = newURL; 
     [newURL release]; 
     [[AVAudioSession sharedInstance] setDelegate: self]; 
     [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: nil]; 

    // Registers the audio route change listener callback function 
    AudioSessionAddPropertyListener (
            kAudioSessionProperty_AudioRouteChange, 
            audioRouteChangeListenerCallback, 
            self 
            ); 

    // Activates the audio session. 

    NSError *activationError = nil; 
    [[AVAudioSession sharedInstance] setActive: YES error: &activationError]; 

    AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: soundFileURL error: nil]; 
    self.appSoundPlayer = newPlayer; 
    [newPlayer release]; 
    [appSoundPlayer prepareToPlay]; 
    [appSoundPlayer setVolume: 1.0]; 
    [appSoundPlayer setDelegate: self]; 
    [appSoundPlayer play]; 

} 

您将被要求使用类似的东西。 这里appSoundPlayer声明在头文件作为

AVAudioPlayer *appSoundPlayer; 

还设置属性给它,

@property(nonatomic, retain)AVAudioPlayer *appSoundPlayer; 

释放它的dealloc方法.. 这是我正在关注的方法和避风港”没有看到任何内存泄漏