2.2、为了优化效播放,减少每次重复加载音效播放,我们将加载音效设为单例
实现单例 —— 将我在前几篇文章说过封装好的的单例宏 直接引用 Singleton.h
创建Singleton.h#import <Foundation/Foundation.h>#import "Singleton.h"@interface SoundTools : NSObject// 单例宏singleton_interface(SoundTools)// 要播放的音效名- (void)playSoundWithName:(NSString *)name;@end将APP要用到的音效添加到新建的bound里去如图:创建Singleton.m#import "SoundTools.h"#import <AudioToolbox/AudioToolbox.h>/** 将所有的音频文件在此单例中统一处理 */@interface SoundTools(){ NSDictionary *_soundDict; // 音频字典}@end@implementation SoundToolssingleton_implementation(SoundTools)- (id)init{ self = [super init]; if (self) { // 完成所有音频文件的加载工作 _soundDict = [self loadSounds]; } return self;}2.3、启动系统声音服务 系统声音服务通过SystemSoundID来播放声音文件,对于同一个声音文件,可以创建多个SystemSoundI。系统声音服务是一套C语言的框架。为了提高应用程序性能,避免声音文件被重复加载,通常采用单例模式处理系统声音的播放Singleton.m 实现#PRagma mark 加载指定的音频文件- (SystemSoundID)loadSoundWithURL:(NSURL *)url{ SystemSoundID soundID = 0; AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID); return soundID;}2.4、加载bound里所有的音效文件,并记录进全局的字典中
#pragma mark 加载所有的音频文件- (NSDictionary *)loadSounds{ // 思考:如何直到加载哪些音频文件呢? // 建立一个sound.bundle,存放所有的音效文件 // 在程序执行时,直接遍历bundle中的所有文件 // 1. 取出bundle的路径名 NSString *mainBundlPath = [[NSBundle mainBundle] bundlePath]; NSString *bundlePath = [mainBundlPath stringByAppendingPathComponent:@"sound.bundle"]; // 2. 遍历目录 NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:bundlePath error:nil]; // 3. 遍历数组,创建SoundID,如何使用? NSMutableDictionary *dictM = [NSMutableDictionary dictionaryWithCapacity:array.count]; [array enumerateObjectsUsingBlock:^(NSString *fileName, NSUInteger idx, BOOL *stop) { // 1> 拼接URL NSString *filePath = [bundlePath stringByAppendingPathComponent:fileName]; NSURL *fileURL = [NSURL fileURLWithPath:filePath]; SystemSoundID soundID = [self loadSoundWithURL:fileURL]; // 将文件名作为键值 [dictM setObject:@(soundID) forKey:fileName]; }]; return dictM;}2.5、播放音频 注意 断言:在项目开发中,防止被无意中修改音效名,找不到要播放的音效文件#pragma mark - 播放音频- (void)playSoundWithName:(NSString *)name{ SystemSoundID soundID = [_soundDict[name] unsignedLongValue]; NSLog(@"%ld",soundID); //断言它必须大于0; NSAssert(soundID > 0, @"%@ 声音文件不存在!", name); AudioServicesPlaySystemSound(soundID);}在控制器里调用按钮的点击事情即可- (void)clickMe{ [[SoundTools sharedSoundTools] playSoundWithName:@"game_overs.mp3"];}2.6、优化之前的代码 —— 每次都会重复加载新的音效// NSURL *url = [[NSBundle mainBundle] URLForResource:@"bullet.mp3" withExtension:nil];// SystemSoundID soundID = 0;// // // 创建声音,并且生成soundID的数值// AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);//// // 播放声音// // 同样遵守苹果的静音原则,如果用户静音,会震动!提示用户注意!// // AudioServicesPlayAlertSound(<#SystemSoundID inSystemSoundID#>)// // 只播放声音,遵守苹果的静音原则 HIG// AudioServicesPlaySystemSound(soundID);//// NSLog(@"%ld", soundID);
新闻热点
疑难解答