你好,歡迎來到IOS教程網

 Ios教程網 >> IOS使用技巧 >> IOS技巧綜合 >> 音效工具類的封裝

音效工具類的封裝

編輯:IOS技巧綜合
[摘要]本文是對音效工具類的封裝的講解,對學習IOS蘋果軟件開發有所幫助,與大家分享。

分析

    音效工具類的職責與便利性
    • 能夠記錄音效文件的SoundID,無需每一次播報音效的時候都需要重新獲取 能夠對存放在系統中的SoundID進行緩存優化處理
    與單例類的比較
    • 單利類的話,一旦我們第一次初始化之後,將不會被釋放,對於緩存的優化處理不友好 類方法(靜態方法),無需初始化對象,每一個類在編譯的時候編譯系統都會開辟對於的內存,性能要稍微優於單利類
    類方法的特點
    • 不能在類方法中調用self.獲取對應的屬性 類方法中既不能用屬性也不用成員變量,但是可以用全局靜態變量

代碼

    SPPSoundPlayManager.h文件
#import <Foundation/Foundation.h>

@interface SPPSoundPlayManager : NSObject

/**
 播放音效
 
 @param name 聲音文件名(帶後綴)
 @param alert 是否振動
 */
+ (void)playSoundWithName:(NSString *)name alert:(BOOL)alert;

//清除緩存
+ (void)clearMemory;

@end
    SPPSoundPlayManager.m文件
#import "SPPSoundPlayManager.h"
#import <AVFoundation/AVFoundation.h>

//全局的靜態變量(static修飾符:靜態變量,只能分配一次內存,即只能初始化一次,只會開辟一次內存空間,不會反復重新加載內存)
//音效緩存字典(key: 文件名name, value: soundID)
static NSMutableDictionary *cacheDict;

@interface SPPSoundPlayManager()

//靜態方法中是無法訪問屬性的,改用C的靜態變量
//@property(nonatomic, strong) NSMutableDictionary *cacheDict;

@end

@implementation SPPSoundPlayManager

//第一次加載當前類(類被加載到內存中)的時候會先執行load方法(1. 只會執行一次 2. 一旦你創建了這一個文件就會在編譯時調用,與你是否使用它無關)
+ (void)load {
    NSLog(@"load");
}

//第一次使用當前類的時候會執行(1. 只會執行一次 2. 你使用了這個類就會執行,不使用則不執行)
+ (void)initialize {
    NSLog(@"initialize");   //類的生命周期
    
    //初始化緩存字典
    cacheDict = [NSMutableDictionary dictionary];
}

/**
 播放系統音效
 
 @param name 音效的文件名(帶後綴)
 @param alert 是否振動
 */
+ (void)playSoundWithName:(NSString *)name alert:(BOOL)alert {

    /**
     1. 以name為Key, SoundID為Value
     2. 先判斷緩存字典對一個的Value是否有值 --> soundID == 0 就代表沒有值/沒有緩存
     3. 沒有值就創建, 有的話直接播放
     */
    
    //1. 創建系統音效soundID
    SystemSoundID soundid = [cacheDict[name] unsignedIntValue];
    
    //2. 先檢查該文件是否在當前緩存文件中(為0代表沒有在緩存中,那就去創建)
    if (soundid == 0) {
        //1. 創建音效類
        //1.1 獲取包中音效文件的url路徑
        NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:nil];
        
        //1.2 音效的播放是由系統底層來播放(基於C的接口)
        ///傳入音頻路徑url就會和soundID進行綁定,之後需要播放的時候, 只需要調用soundID, 就能找到對應的URL地址
        ///這樣做的好處就是soundID對音效有一個緩存,當音效文件第一次加載時,系統會將音效文件隨機分配一個soundID,可以在下次播放時直接使用soundID播放,而無需再次獲取對應的url地址
        AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundid);
        
        //1.3 將文件名與soundid加入到緩存字典中
        [cacheDict setValue:@(soundid) forKey:name];
    }
    
    //3. 播放音效(音效: 不超過30s的短音樂)
    ///播放音效有兩種類型,一種是帶振動(必須要真機),一種不帶振動
    if (alert) {
        //帶振動
        AudioServicesPlayAlertSound(soundid);
        
    }else {
        //不帶振動
        AudioServicesPlaySystemSound(soundid);
    }
}

+ (void)clearMemory {
    //1. 靜態變量字典在ARC下面釋放內存不能直接設置為nil,應該先清除內部對象
    [cacheDict enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        //2. 清除靜態字典內部的緩存
        ///ARC只對OC對象有效,對C對象無效(這就是為什麼C對象至今仍保留了retain和release方法)
        //2.1 獲取緩存的soundID
        SystemSoundID soundID = [obj unsignedIntValue];
        //2.2 C對象要釋放一般使用CFRelease(),注意是釋放C對象(堆裡),而soundID是UInt32類型(棧裡),所以看出有一些特殊的系統類內部會給出單獨的API用於釋放,此時應優先使用系統給出的單獨的API,而不能一味套用CFRelease()
        //Dispose: 處理int類型的棧內存不能直接使用release
        AudioServicesDisposeSystemSoundID(soundID);
        
    }];
    //3. 移除字典所有元素
    [cacheDict removeAllObjects];
}

@end
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved