这个问题可能过于模糊,不能通过StackOverflow's
标准,但我必须尝试发布它,因为我的选项用完了......:/
长话短说:我的应用程序经历了随机的缓慢时期。它不会经常发生(可能每个月一次),但是当它运行的iDevice 仅完全重启时会有帮助。症状是:2-3秒的响应时间和缓慢,波动的动画;整个应用程序基本上变得无法使用。
我通过各种可能的诊断工具运行应用程序,其中没有发现任何错误;没有内存泄漏或异常高的CPU使用率。但是,这并不奇怪,考虑到应用程序非常简单,一个卡片游戏的跟踪器应用程序。
所有这些让我相信,当用户点击AVAudioPlayer
时,我用来播放声音的button
可能是导致问题的原因(它是唯一的,相对较高的复杂因素)整个应用程序)。但是,我不确定,这是我需要帮助的地方。我在这里提供了一个示例代码,也许有iOS
音频播放经验的人可以查看它,看看是否有一些我忽略的错误。
我们走了:
首先,我初始化一个“静音播放器”,每秒钟保持播放一个静音音轨以保持AVAudioPlayer
活着。这是必要的,因为在长时间不活动后被调用时,响应时间相对较长AVAudioPlayer
。
NSString *silenceFilePath = [[NSBundle mainBundle] pathForResource: @"silence" ofType: @"wav"];
NSURL *silenceFileURL = [[NSURL alloc] initFileURLWithPath: silenceFilePath];
silencePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: silenceFileURL error: nil];
[silencePlayer setDelegate: self];
[silencePlayer prepareToPlay];
silenceTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(repeatSilence)
userInfo:nil
repeats:YES];
NSTimer调用以下方法:
- (void) repeatSilence
{
if (isAudioON == YES)
{
if (silencePlayer.playing)
{
[silencePlayer stop];
silencePlayer.currentTime = 0;
[silencePlayer play];
}
else
{
[silencePlayer play];
}
}
}
其余的相当简单。我启动另一个AVAudioPlayer来播放特定的按钮声音(其中有两个):
NSString *buttonSoundFilePath = [[NSBundle mainBundle] pathForResource: @"button_pushed" ofType: @"wav"];
NSURL *buttonFileURL = [[NSURL alloc] initFileURLWithPath: buttonSoundFilePath];
buttonPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: buttonFileURL error: nil];
[buttonPlayer setDelegate: self];
[buttonPlayer prepareToPlay];
当按下按钮时,我播放声音(就像我对静音播放器一样):
if (isAudioON == YES)
{
if (buttonPlayer.playing)
{
[buttonPlayer stop];
buttonPlayer.currentTime = 0;
[buttonPlayer play];
}
else
{
[buttonPlayer play];
}
}
真的就是它。然而,我担心,尽管这种方法具有简单的特性,但不知何故,这种连续的音频播放创造了一个罕见的例子,其中iOS只是疯了。但这只是一个理论,这就是为什么我需要有经验的人来看看我的代码并分享他的意见。
谢谢!
更新 我发现了另外几行代码也可能与问题有关。有了它们,我将AVAudioPlayer设置为与在后台播放音乐同时工作(例如,从另一个应用程序):
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
[[AVAudioSession sharedInstance] setDelegate:self];
答案 0 :(得分:4)
从我的问题中收集到的,似乎你想要播放的唯一声音是相对简单和短的声音效果。如果实际上是这种情况,我就不会使用AVAudioPlayer,因为它是一个资源丰富的库,可以像在固定音量下播放音效一样简单。我会直接使用音频服务。这是我从其他地方拉出的音效类的一个例子(不记得在哪里)。
SoundEffect.h
#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>
@interface SoundEffect : NSObject
{
SystemSoundID soundID;
}
- (id)initWithSoundNamed:(NSString *)filename;
- (void)play;
@end
SoundEffect.m
#import "SoundEffect.h"
@implementation SoundEffect
- (id)initWithSoundNamed:(NSString *)filename
{
if ((self = [super init]))
{
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];
if (fileURL != nil)
{
SystemSoundID theSoundID;
OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)fileURL, &theSoundID);
if (error == kAudioServicesNoError)
soundID = theSoundID;
}
}
return self;
}
- (void)dealloc
{
AudioServicesDisposeSystemSoundID(soundID);
}
- (void)play
{
AudioServicesPlaySystemSound(soundID);
}
@end
完成本课程后,您可以使用以下代码轻松播放任何音效:
SoundEffect *mySoundEffect = [[SoundEffect alloc] initWithSoundNamed:@"mySound.wav"];
[shareSoundEffect play];
为了优化,我会在某处加载所有声音效果并静态存储它们,以便预先加载实际的声音文件,然后只要你需要它们就可以在它们上面调用“play”。与使用AVAudioPlayer相比,这样做比播放声音效果的资源更少。谁知道,也许它会解决你的问题。
预加载声音文件:
我的意思是这比听起来简单。我只是意味着在程序首次加载时初始化后,您将为每个Sound Effect对象创建一个静态引用。有几种方法可以做到这一点。我通常使用+ load方法。它看起来像这样:
在SoundEffect类的实现中添加一个静态变量
static SoundEffect *mySoundEffect;
接下来,在Sound Effect类的+ load方法中初始化该变量。
+(void)load
{
mySoundEffect = [[SoundEffect alloc] initWithSoundNamed:@"mySound.wav"];
}
现在只需为声音效果类创建一个静态方法,如下所示:
+(void)playMySound
{
[mySoundEffect play];
}
之后,您可以随时拨打:
播放该声音[SoundEffect playMySound];
关于音量控制的说明:
我在我的几个IOS应用程序中使用此代码,我可以确认以下内容:
答案 1 :(得分:1)
我从上面的代码中看到,我建议做两处修改。
1)您使用了两个AVAudioPlayer实例,一个用于每秒连续播放静音。 AVAudioPlayer的第二个实例用于在单击按钮时播放声音。同时运行两个AVAudioPlayer实例,因为在设备内存不足的某个时间点,需要同时播放静音和按键声音时设备会缓慢运行。最好使用一个AVAudioPlayer实例来播放这两种声音。
2)继续播放静音,直到用户点击按钮。当用户单击该按钮时,暂停计时器并停止当前声音并使用相同的AVAudioPlayer实例播放按钮声音。这样,当需要播放按钮声时,当按钮声音播放完毕时,不推荐的计时器将停止一段时间,当按钮声音结束播放时,恢复计时器以播放与AVAudioPlayer实例相同的静音。这将从内存和处理中消除大量负载。