我喜欢应用程序的键盘,我将每个新的AVAudioPlayer添加到NSMutableArray,这样我就能叠加声音。 我的问题是,那个delagate功能
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
如果在短间隔内有击键,则不会触发。如果我以0.5秒或更长的间隔行程,一切正常。知道为什么吗? 我希望释放内存并在声音播放结束后从数组中删除对象。
更新
·H
@interface .. <AVAudioPlayerDelegate>
{
NSMutableArray *soundObjects;
}
@property (nonatomic,strong) AVAudioPlayer *audioPlayer;
的.m
-(void)playSound {
//
// play sound
//
_audioPlayer = [self loadWav:_soundID];
_audioPlayer.delegate = self;
[soundObjects addObject:_audioPlayer];
AVAudioPlayer *temp = [soundObjects objectAtIndex:soundIndex];
soundIndex = [soundObjects count];
[temp play];
}
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
#ifdef DEBUG_SOUND
NSLog(@"FLAG");
soundIndex--;
[soundObjects removeObjectAtIndex:soundIndex];
#endif
}
- (AVAudioPlayer *)loadWav:(NSString *)filename {
NSURL * url = [[NSBundle mainBundle] URLForResource:filename withExtension:@"mp3"];
NSError * error;
AVAudioPlayer * player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if (!player) {
#ifdef DEBUG_MODE
NSLog(@"Error loading %@: %@", url, error.localizedDescription);
#endif
} else {
[player prepareToPlay];
}
return player;
}
答案 0 :(得分:0)
尝试在后台进程中触发播放。这是我的第一次,但在不知道更多具体细节的情况下,我只能推测你是如何演奏声音的。如果您正在主线程上播放声音,那么同时在同一线程上缓冲和触发声音时,主线程上的键盘也将无响应。在处理媒体时,您通常应加载它并将其从主线程中播放,以消除竞争条件的可能性。如果将图像加载到歌曲或电影中,它通常不应该在主线程上,因为UI将无响应。
答案 1 :(得分:0)
在开发人员文档中有几个NSQueue的例子,我将使用我用自己的工作整理的Obj C Recipe书中的改编。
//This method detatches the instruction from the main thread
-(void)keyStrokeSelector:(NSString*)objectSound{
[NSThread detachNewThreadSelector:@selector(keyStroke:objectSound)
toTarget:self
withObject:nil];
}
//this selector will acctually execute the task
-(void)keyStroke:(NSString *)objectSound
{
@autoreleasepool {
//code to play the sound
}
}
我希望这会有所帮助。关于上面代码的一些注意事项:你必须为每个单独的线程使用自动释放池,否则引用计数(MRC或ARC)将无法工作,因为它只能在自动释放池中工作,在主线程的线程中发生的代码应该被编码像其他任何东西一样,它只会执行并运行完成。如果您在子线程中有一个无限循环,那么在测试您的应用程序时可能不会引起注意,但是如果我正确记住了后台线程的当前最大时间,操作系统将在十分钟后终止应用程序。更重要的是,如果你没有创建一个特定于@autoreleasepool的线程那么我就不能强调这一点,那么即使你没有在新线程中创建一个新对象,当它们被传入时你的对象也不会被释放并且会占用内存占用量。他们将获得保留计数并留在记忆中。
我希望这会对您的计划有所帮助