【发布时间】:2012-08-13 09:08:01
【问题描述】:
我继承了一些需要整理的代码。该应用程序有一些核心声音,目前,有很多 AVAudioPlayer 实例附加到各种 ViewController 都播放相同的几个声音。
作为重构练习的一部分,我决定实现一个名为SoundController 的单例类。这个类将为每个需要播放的声音包含一个 AVAudioPlayer,而不是每个 ViewController 实例化自己的,他们可以轻松地只使用一个:
[[SoundController controller].majorFunctionSound playAtTime:0];
另一件重要的事情是确保在所有声音被使用之前都已调用 prepareToPlay: 以最大程度地减少任何延迟。由于只有少数声音并且它们都可能在任何用户会话期间使用,因此在 SoundController 首次实例化时预加载所有声音(在后台线程上)是有意义的。在 init 方法中我有这样的东西:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, nil, ^(void)
{
NSURL *soundURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/MAJOR FUNCTION.m4a", [[NSBundle mainBundle] resourcePath]]];
_majorAudioSound = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:nil];
[_majorAudioSound prepareToPlay];
});
majorAudioSound 是 (readonly, strong)。 @synthesize majorAudioSound = _majorAudioSound.
我担心的是,这在并发方面的工作效果有多差(或好不好),以及我可以做些什么来改进代码。具体来说,如果我这样做:
[[SoundController controller].majorFunctionSound playAtTime:0];
很明显,majorFunctionSound 有可能无法正确启动,具体取决于后台初始化块是否已完成。如果属性返回 nil 并且声音根本无法播放,是否会发生更糟糕的情况?
可能还有什么其他问题?有没有办法始终确保 AVAudioPlayer 已正确设置?
【问题讨论】:
标签: objective-c ios concurrency avaudioplayer objective-c-blocks