我继承了一些需要稍微整理的代码。该应用程序有一些核心声音,目前,有很多AVAudioPlayer
实例附加到各种ViewController
的播放相同的几个声音。iOS:在后台加载声音时出现多线程问题
作为重构练习的一部分,我决定实现一个名为SoundController
的单例类。本课程将包含一个需要打每个声音一个AVAudioPlayer
,而是每个ViewController
的实例自己,他们可以很容易地利用只是一个:
[[SoundController controller].majorFunctionSound playAtTime:0];
另一个重要的事情是确保prepareToPlay:已在所有声音被用于最小化任何延迟之前呼吁所有声音。由于只有少数几个声音,并且它们都可能在任何用户会话期间使用,因此在SoundController首次实例化时预先加载所有声音(在后台线程上)是有意义的。在初始化方法我有这样的事情:
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的设置正确?
我很期待这样做,因为这将是我通常会用其他语言(IOC等)的方法。我会玩一玩,然后尝试并实施您的建议 - 我期待的是让视图控制器中的声音数量达到最小。 另外,请你能详细解释一下你最后一句话吗? – djskinner 2012-08-13 12:36:26
“记住保持该属性的处理同步” - 意味着如果您正在从多个线程访问资源,则需要确保此线程不被同时读写。您可以使用@ synchronized-blocks或使用原子属性(非非原子)并通过getter/setter方法访问它们。 – 2012-08-13 13:23:04
通过试图避免viewcontroller类中的代码,您正在定义正确的轨道。保持最小值可以为您节省大量头痛,并使您的应用程序更易于维护,扩展和重用。保持! – 2012-08-13 13:23:32