Iphone AVAudioPlayer与随机慢度

Iphone AVAudioPlayer与随机慢度,iphone,ios,objective-c,audio,avaudioplayer,Iphone,Ios,Objective C,Audio,Avaudioplayer,这个问题可能太模糊,无法通过StackOverflow的标准,但我必须尝试发布它,因为我没有选择了…:/ 长话短说:我有一个应用程序经历了随机的缓慢时期。这种情况并不经常发生(可能每个月一次),但当它发生时,只有完全重新启动它所运行的iDevice才有帮助。症状为:2-3秒的反应时间和缓慢、起伏的动画;整个应用程序基本上无法使用 我用了所有可能的诊断工具运行了这个应用程序,没有发现任何错误;没有内存泄漏或异常高的CPU使用率。但是,这并不奇怪,因为这款应用非常简单,是一款用于纸牌游戏的追踪应用

这个问题可能太模糊,无法通过StackOverflow的标准,但我必须尝试发布它,因为我没有选择了…:/

长话短说:我有一个应用程序经历了随机的缓慢时期。这种情况并不经常发生(可能每个月一次),但当它发生时,只有完全重新启动它所运行的iDevice才有帮助。症状为:2-3秒的反应时间和缓慢、起伏的动画;整个应用程序基本上无法使用

我用了所有可能的诊断工具运行了这个应用程序,没有发现任何错误;没有内存泄漏或异常高的CPU使用率。但是,这并不奇怪,因为这款应用非常简单,是一款用于纸牌游戏的追踪应用

所有这一切让我相信,当用户点击
按钮时,我用来播放声音的
AVAudioPlayer
可能是问题的原因(它是整个应用程序中唯一相对复杂的元素)。然而,我不确定我需要帮助的地方在哪里。我在这里提供了一个示例代码,也许有人在
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来播放特定的按钮声音(有两种):

当按下按钮时,我播放声音(与静音播放器的播放方式相同):

事实上,这就是一切。然而,我担心,尽管这种方法很简单,但这种连续的音频播放却创造了一个罕见的实例,让iOS变得疯狂。但所有这些都只是一个理论,这就是为什么我需要有更多经验的人来看看我的代码并分享他的观点

谢谢

更新: 我发现另外几行代码可能也与问题有关。使用它们,我将AVAudioPlayer设置为与背景音乐播放同时工作(例如,从另一个应用程序):


根据我从上面代码中观察到的情况,我建议进行两项更改

1) 您已经使用了两个AVAudioPlayer实例,其中一个用于每秒连续播放无声声音。AVAudioPlayer的第二个实例用于在单击按钮时播放声音。同时运行两个AVAudioPlayer实例,例如在设备内存不足的某个时间点,需要同时播放静音和按钮声音,设备将动作迟缓。最好使用一个AVAudioPlayer实例来播放两种声音


2) 继续播放静音,直到用户单击按钮。当用户单击按钮时,暂停计时器并停止当前声音,然后使用相同的AVAudioPlayer实例播放按钮声音。这样,当需要播放按钮声音时,通常不推荐的计时器将停止一段时间,当按钮声音播放完毕后,恢复计时器以播放相同AVAudioPlayer实例的无声声音。这将从内存和处理中带走大量的负载。

从我从您的问题中收集的信息来看,您想要播放的声音似乎只有相对简单和简短的音效。如果事实上是这样,我就不会使用AVAudioPlayer,因为它是一个资源密集型的库,用于以固定音量播放音效这样简单的事情。我会直接使用音频服务。这里是一个我从其他地方(不记得在哪里了)提取的声音效果类的示例

音响效果

#import <Foundation/Foundation.h>
#import <AudioToolbox/AudioToolbox.h>

@interface SoundEffect : NSObject
{
    SystemSoundID soundID;
}

- (id)initWithSoundNamed:(NSString *)filename;
- (void)play;

@end
拥有该类后,您可以使用以下代码轻松播放任何音效:

SoundEffect *mySoundEffect = [[SoundEffect alloc] initWithSoundNamed:@"mySound.wav"];
[shareSoundEffect play];
为了优化,我将把你所有的声音效果加载到某个地方并静态存储,这样实际的声音文件就可以预加载,然后只要在你需要的时候调用“播放”就可以了。与使用AVAudioPlayer相比,使用这种方式播放音效的资源消耗要少得多。谁知道呢,也许这会解决你的问题

预加载声音文件:

我的意思比听起来简单。我的意思是,当程序首次加载时,在初始化每个音效对象之后,您将为它们创建一个静态引用。有几种方法可以做到这一点。我通常使用+load方法。它看起来像这样:

+(void)playMySound
{
    [mySoundEffect play];
}
在SoundEffect类的实现中添加一个静态变量

static SoundEffect *mySoundEffect;
接下来,在Sound Effect类的+load方法中初始化该变量

+(void)load
{
    mySoundEffect = [[SoundEffect alloc] initWithSoundNamed:@"mySound.wav"];
}
现在只需为sound effect类创建一个静态方法,如下所示:

+(void)playMySound
{
    [mySoundEffect play];
}
之后,您可以随时通过调用以下命令播放该声音:

[SoundEffect playMySound];
有关音量控制的说明:

我在几个IOS应用程序中使用此代码,我可以确认以下内容:

  • 设备一侧的标准音量控制将正常工作,但前提是用户的设置指定可以使用按钮更改振铃器和警报
  • 无法控制代码中的音量
    我一定会试试这个。但是,我注意到代码中有SystemSoundID变量。这是否意味着您的方法使用系统声音对象来播放声音?如果是这样的话,我的问题是使用系统声音时缺乏值控制。我试过了。另外,您能否提供一个如何“预加载”声音文件的示例?我不熟悉这种做法。没错,在这种情况下,您将无法通过编程控制音效的音量。如果你需要声音效果在一个较低或较高的音量,你需要有不同的
    +(void)load
    {
        mySoundEffect = [[SoundEffect alloc] initWithSoundNamed:@"mySound.wav"];
    }
    
    +(void)playMySound
    {
        [mySoundEffect play];
    }
    
    [SoundEffect playMySound];