一次性执行
还没有被执行的时候onceToken的值是0,如果已经被执行过了onceToken会变成非0
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// for (int i =0; i<100; i++) {
// [self demo1];
// }
for (int i =0; i<100; i++) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self demo1];
});
}
}
// 一次性执行
// 线程安全的
- (void)demo1{
static dispatch_once_t onceToken;
NSLog(@"%ld",onceToken);
dispatch_once(&onceToken, ^{
NSLog(@"demo");
});
}
单例模式
场景:
(1) 网易云音乐的播放器界面
(2)固定的配置文件(plist/text)需要把这个配置转化成对象,对配置文件进行修改
单例实现的两种方式
单例的实现方法有两种,一种是使用dispatch_once,另一种则是使用同步锁,他们的具体实现如下
.h文件
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface BBConfig : NSObject
// 返回唯一的一个对象(单例):整个系统中只有唯一一个类的对象(性能高,苹果推荐写法)
+ (instancetype)config;
// 同步锁实现单例(性能差)
+ (instancetype)configSync;
@end
NS_ASSUME_NONNULL_END
.m文件
#import "BBConfig.h"
@implementation BBConfig
+ (instancetype)config{
static BBConfig *instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[BBConfig alloc] init];
});
return instance;
}
+ (instancetype)configSync{
static BBConfig *instance;
@synchronized (self) {
if (instance == nil) {
instance = [[BBConfig alloc] init];
}
}
return instance;
}
@end
性能上来说,dispatch_once的性能较好,因为同步锁synchronized涉及到线程的调度(主要是等待),同事dispatch_once也是苹果推荐的单例写法。
网友评论