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);
新聞熱點
疑難解答