我可以在NSMutableArray中存储AVAudioPlayer引用并随意播放它们吗?

时间:2010-06-19 01:10:27

标签: iphone objective-c nsmutablearray avaudioplayer

我有一个包含16个短声道片段的库,我需要能够快速连续播放。我意识到实时创建和准备AVAudioPlayer个对象对于iPhone来说太过分了。

所以相反,在我的应用初始化期间,我预先创建了一系列AVAudioPlayers,这样每个人基本上都预装了我的16个声音中的一个,所以他们已经准备好在任何时候播放时间。

问题是,为了保持干净,我想将这些16 AVAudioPlayers的引用存储在NSMutableArray中,这样我就可以通过了解它们的数组位置轻松地获取它们。但是,我这样做的方式是在日志中没有错误消息的情况下崩溃模拟器:

以下是我目前正在设置AVAudioPlayer引用数组的方法:

// (soundPlayers is an NSMutableArray instance var)
soundPlayers = [NSMutableArray arrayWithCapacity:(NSUInteger)16];                                       

for ( int i = 0; i < 16; i++ ) {
    NSString *soundName = [NSString stringWithFormat:@"sound-%d", i];
    NSString *soundPath = [[NSBundle mainBundle] pathForResource:soundName ofType:@"mp3"];
    NSURL *soundFile = [[NSURL alloc] initFileURLWithPath:soundPath];   
    AVAudioPlayer *p = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFile error:nil];
    [soundFile release];
    [p prepareToPlay];
    [soundPlayers addObject:(id)p];
    [p release];
}

然后我试着加载声音#8并播放它:

// (soundPlayer is an AVAudioPlayer instance var)
self.soundPlayer = [soundPlayers objectAtIndex:(NSUInteger)8];
[soundPlayer play]; 

有什么想法吗?也有人知道XCode附带的任何光滑的调试工具是否对这类问题有用?

3 个答案:

答案 0 :(得分:2)

我只是在这里猜测,但阵列的容量可能存在问题。

请尝试:soundPlayers = [[NSMutableArray alloc] init];

这可能不是导致崩溃的原因,但在调用self.soundPlayer之前尝试NSLogging -play以确保其不是nil。另一个小问题:将数据添加到数组时,不需要对p进行类型转换。只需拨打[soundPlayers addObject:p],不要(id)

我不确定崩溃的确切原因,只是查看代码并指出哪些内容不正确。希望这有帮助!

答案 1 :(得分:1)

最有可能的情况是,您的soundPlayers可变数组在某些时候被释放,因为您没有保留它。我会确保你的数组属性设置为保留并执行Macatomy之前所说的:

self.soundPlayers = [[NSMutableArray alloc] init];

甚至是initWithCapacity:

答案 2 :(得分:0)

对我来说看起来没问题,除非您在将它们放入数组之前不应该调用prepareToPlay

当你打算玩它们时,最好这样做。该方法的描述表明它预加载缓冲区并获取音频硬件以进行回放。一次做16次可能太多了。

编辑 - 你还应该添加错误检查,你可能会告诉你错误的结果,initWithContentsOfURL:outError:返回错误信息。利用这个:

NSError* error = nil;
AVAudioPlayer *p = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFile error:&error];
if (error) {
    NSLog(@"ERROR: %@, URL=%@", error.localizedDescription, soundFile);
}