Dispatch Once

dispatch_once函数保证在应用程序中只会执行一次指定处理的API.

dispatch_once_t必须是全局或者static变量。实际上也就是保证dispatch_once_t是全局唯一, Xcode默认已经提供了代码块直接生成代码。

1
2
3
4
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 初始化
});

dispatch_once 即使在多线程环境下,也保证安全。

所以dispatch_once常常用来生成单例对象,或者一些重型资源。

单例

  • 声明静态变量来保存这个实例
  • 声明一个静态的dispatch_once_t,保证初始化代码只会执行一次
  • 代码块中执行初始化,一个类只能被实例化一次
1
2
3
4
5
6
7
8
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}

其他的使用场景

NSDateFormatter、NSCalendar、NSDateComponentsFormatter等初始化非常慢,那么就可以想到重用这个对象。在类中添加属性或者静态变量。还有一些调用很频繁的属性。

NSDateFormatter

1
2
3
4
5
6
7
8
9
static NSString *LZStringFromDateISO8601(NSDate *date) {
static NSDateFormatter *formatter = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd"];
});
return [formatter stringFromDate:date];
}

NSCalendar

1
2
3
4
5
6
7
8
NSCalendar *LZTimeOfDayReferenceCalendar() {
static NSCalendar *calendar;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
});
return calendar;
}

screenScale

这个也是大量的用到。

1
2
3
4
5
static CGFloat screenScale = 1.0;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
screenScale = [UIScreen mainScreen].scale;
});
坚持原创技术分享,您的支持将鼓励我继续创作!