分析
- 音效工具类的职责与便利性
- 能够记录音效文件的SoundID,无需每一次播报音效的时候都需要重新获取
- 能够对存放在系统中的SoundID进行缓存优化处理
- 与单例类的比较
- 单利类的话,一旦我们第一次初始化之后,将不会被释放,对于缓存的优化处理不友好
- 类方法(静态方法),无需初始化对象,每一个类在编译的时候编译系统都会开辟对于的内存,性能要稍微优于单利类
- 类方法的特点
- 不能在类方法中调用
self.
获取对应的属性 - 类方法中既不能用属性也不用成员变量,但是可以用全局静态变量
代码
#import <Foundation/Foundation.h>
@interface SPPSoundPlayManager : NSObject
+ (void)playSoundWithName:(NSString *)name alert:(BOOL)alert;
+ (void)clearMemory;
@end
#import "SPPSoundPlayManager.h"
#import <AVFoundation/AVFoundation.h>
static NSMutableDictionary *cacheDict;
@interface SPPSoundPlayManager()
@end
@implementation SPPSoundPlayManager
+ (void)load {
NSLog(@"load");
}
+ (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. 没有值就创建, 有的话直接播放
*/
SystemSoundID soundid = [cacheDict[name] unsignedIntValue];
if (soundid == 0) {
NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:nil];
AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundid);
[cacheDict setValue:@(soundid) forKey:name];
}
if (alert) {
AudioServicesPlayAlertSound(soundid);
}else {
AudioServicesPlaySystemSound(soundid);
}
}
+ (void)clearMemory {
[cacheDict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
SystemSoundID soundID = [obj unsignedIntValue];
AudioServicesDisposeSystemSoundID(soundID);
}];
[cacheDict removeAllObjects];
}
@end