0

几分钟前我发布了一个更长的问题,并且通常我一发布它就知道发生了什么,所以我删除了它,因为大部分帖子都无关紧要。然后我回到谷歌。

事实证明,我遇到了与这篇文章中描述的几乎完全相同的问题,从 6 月开始没有得到答复。http://www.iphonedevsdk.com/forum/iphone-sdk-development/20975-avaudioplayer-nsurl-memory-management.html

总之:我正在使用 AVAudioPlayer 并使用 audioPlayerDidFinishPlaying:successfully: 委托方法发布它。初始化播放器后,需要释放其关联的 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];

对 Steve Riggins 的回应:如前所述,它的诀窍在于它不会每次都同时崩溃。它几乎总是第一次正确释放(或者至少它不会崩溃或泄漏),但通常在我第二次分配/释放播放器和 URL 之后,它在释放 URL 时崩溃。有时,它会在崩溃之前运行 3、4、5 次以上,但它总是如此。

4

2 回答 2

1

创建播放器时释放 URL。我在我的应用程序中执行此操作,它运行良好。没有泄漏,崩溃等

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

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

编辑:如果您的 url 仍然泄漏,您需要在创建它时查看您在做什么。它应该是这样的:

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

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

于 2010-02-04T23:15:25.437 回答
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 方法中释放它。这是我正在遵循的方法,没有看到任何内存泄漏

于 2010-02-05T02:51:28.407 回答