NSSound isPlaying在Mac上返回null

时间:2011-11-30 14:36:47

标签: objective-c xcode nssound

在我的AppDelegate中,我有这个方法,它会在点击播放按钮时运行:

- (IBAction)actionPlayTrack:(id)sender {
    NSSound *currentSong = [[NSSound alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"03 Bazel" ofType:@"mp3"] byReference:YES];
    if([currentSong isPlaying] == NO){
        [currentSong play];
    } else {
        [currentSong stop];
        [currentSong release];
    }
}

然而,检查歌曲当前正在播放的if语句将不起作用,并且无论是否已播放声音,都将始终播放。有什么想法,为什么会这样做?也许每次点击按钮时都会重置currentSong对象,这是我的第一次猜测......

[currentSong isPlaying] 

将始终返回null。

3 个答案:

答案 0 :(得分:3)

我认为问题是每次调用此方法时都要创建一个新的NSSound实例。所以旧的NSSound实例可能正在播放,但这不是。这可能会导致内存泄漏,因为您分配了一个新实例,但从未发布旧实例。

要解决此问题,您可能需要在类中添加NSSound * currentSong,然后在想要检查其是否正在播放时可以使用该NSSound对象。然后,当您切换轨道时,您可能希望在创建新的NSSound实例之前停止现有的NSSound对象并将其释放。

因此,您的代码应该类似于:

- (IBAction)actionPlayTrack:(id)sender {
    if (!currentSong) {
        currentSong = [[NSSound alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"03 Bazel" ofType:@"mp3"] byReference:YES];
    }

    if ([currentSong isPlaying]){
        [currentSong stop];
        [currentSong release];
        currentSong = nil;
    } else {
        [currentSong play];
    }
}

- (void)dealloc {
    [currentSong release];
    currentSong = nil;
}

然后将NSSound* currentSong添加到标题中。

答案 1 :(得分:0)

此提示可能无法解决您的问题,但绝不会将任何内容与YES或NO进行比较。你的测试应该是:

if (![currentSong isPlaying])

原因是NO和YES是单个值,而可能计为true的值是无限的。

答案 2 :(得分:0)

它将始终返回NO,因为您正在询问您刚刚创建的声音是否正在播放,当然不是。

您可能需要使用AudioSession功能来检查设备是否已播放其他内容:

UInt32 otherAudioIsPlaying;
UInt32 propertySize = sizeof( UInt32 );

AudioSessionGetProperty
(
    kAudioSessionProperty_OtherAudioIsPlaying,
    &propertySize,
    &otherAudioIsPlaying
);

检查Audio Session Programming Guide