版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Small_years/article/details/81567255
一直疑惑游戏里面的多个音效同时播放是怎么实现的,今天终于弄明白了,单例实现,看代码:
YJAudioTool.h
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@interface YJAudioTool : NSObject
+(instancetype)sharedAudioTool;
//播放音乐(可以同时播放多个音乐)
-(AVAudioPlayer *)playMusic:(NSString *)fileName;
-(void)pauseMusic:(NSString *)fileName;
-(void)stopMusic:(NSString *)fileName;
//播放音效
-(void)playSound:(NSString *)soundName;
-(void)disposeSound:(NSString *)soundName;//摧毁音效
@end
YJAudioTool.m
#import "YJAudioTool.h"
static YJAudioTool *_instance = nil;
@interface YJAudioTool()
@property (nonatomic,strong)NSMutableDictionary *musicPlayers;
@property (nonatomic,strong)NSMutableDictionary *soundIDs;
@end
@implementation YJAudioTool
+ (instancetype)sharedAudioTool{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (_instance == nil) {
_instance = [[YJAudioTool alloc]init];
}
});
return _instance;
}
+(id)allocWithZone:(struct _NSZone *)zone{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (_instance == nil) {
_instance = [super allocWithZone:zone];
}
});
return _instance;
}
-(instancetype)init{
__block YJAudioTool *temp = self;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if ((temp = [super init]) != nil) {
//初始化变量
_musicPlayers = [NSMutableDictionary dictionaryWithCapacity:3];
_soundIDs = [NSMutableDictionary dictionaryWithCapacity:3];
}
});
self = temp;
return self;
}
-(id)copy{
return _instance;
}
-(id)mutableCopy{
return _instance;
}
//单例方法
-(AVAudioPlayer *)playMusic:(NSString *)fileName{
if (!fileName || fileName.length == 0) {
return nil;
}
AVAudioPlayer *player = self.musicPlayers[fileName];
if (!player) {
NSURL *musicURL = [[NSBundle mainBundle]URLForResource:fileName withExtension:nil];
if (!musicURL) {
return nil;
}
player = [[AVAudioPlayer alloc]initWithContentsOfURL:musicURL error:nil];
if(![player prepareToPlay]){
return nil;
}
self.musicPlayers[fileName] = player;
}
if (!player.isPlaying) {
[player play];
}
return player;
}
//暂停
-(void)pauseMusic:(NSString *)fileName{
if (!fileName || fileName.length == 0) {
return;
}
AVAudioPlayer *player = self.musicPlayers[fileName];
if(player.isPlaying){
[player pause];
}
}
//停止
-(void)stopMusic:(NSString *)fileName{
if (!fileName || fileName.length == 0) {
return;
}
AVAudioPlayer *player = self.musicPlayers[fileName];
[player stop];
}
//播放音效
-(void)playSound:(NSString *)soundName{
if (!soundName || soundName.length == 0) {
return;
}
SystemSoundID soundID = (int)[self.soundIDs[soundName] unsignedLongValue];
if (!soundID) {
NSURL *url = [[NSBundle mainBundle]URLForResource:soundName withExtension:nil];
if (!url){
return;
}
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(url), &soundID);
self.soundIDs[soundName] = @(soundID);
}
AudioServicesPlaySystemSound(soundID);
}
// 摧毁音效
-(void)disposeSound:(NSString *)soundName{
if (!soundName) return;
SystemSoundID soundID = (int)[self.soundIDs[soundName] unsignedLongValue];
if (soundID) {
AudioServicesDisposeSystemSoundID(soundID);
[self.soundIDs removeObjectForKey:soundName]; //音效被摧毁,那么对应的对象应该从缓存中移除
}
}
@end
viewcontroller中的使用:
-(void)firstStartMusic{
NSLog(@"播放声音1");
[[YJAudioTool sharedAudioTool]playMusic:@"123.mp3"];
}
-(void)firstPauseMusic{
NSLog(@"暂停声音1");
[[YJAudioTool sharedAudioTool]pauseMusic:@"123.mp3"];
}
-(void)secStartMusic{
NSLog(@"播放声音2");
[[YJAudioTool sharedAudioTool]playMusic:@"林俊杰-江南.mp3"];
}
-(void)secPauseMusic{
NSLog(@"暂停声音2");
[[YJAudioTool sharedAudioTool]pauseMusic:@"林俊杰-江南.mp3"];
}
个人疑问:每次播放一个声音之前,根据音效的名字创建的每一个player对象,都存放到了一个数组中,这样是不是违背了单例的原则?有大神明白的话,下方留言,不吝赐教。