iOS单例

单例

整个程序中某个类只存在一份实例;
一旦创建,程序结束后才会销毁回收内存;
单例对象指针保存在静态区,单例对象存在堆中分配的内存空间;

苹果本身API存在的单例:

1
2
3
4
UIApplication
NSNotificationCenter
NSUserDefaults
NSFileManager

优点:
整个程序中只会实例化一次,程序出现问题比较容易定位;
只会实例化一次,节省内存;
缺点:
不能被继承,没有子类,不能扩展和重写;
程序运行过程中一直占着内存,单例创建过多时和闲置时会占用内存资源;

单例的创建方式

@synchronized

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.h  
+(Common *)sharedInstance;

.m
+(Common *)sharedInstance{
static Common *common = nil;//static修饰,只初始化一次,修改实例生命周期,程序结束后才会回收;
@synchronized (common) {//线程安全
if (common == nil) {
common = [[Common alloc]init];
}
}
return common;
}
打印的内存地址:
NSLog(@"\n1:%p\n2:%p\n3:%p\n",[Common sharedInstance],[Common sharedInstance],[Common sharedInstance]);
2020-04-13 10:24:20.471536+0800 Dispatch(线程安全)[32199:1460720]
1:0x600000d5b640
2:0x600000d5b640
3:0x600000d5b640

dispatch_once

为了数据和线程安全,苹果官方推荐使用这种方式进行创建单例;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.h
+(Common *)sharedInstanceOnce;

.m
#import "Common.h"
static Common *common1 = nil;
@implementation Common
+(Common *)sharedInstanceOnce{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{//只会被执行一次并且线程安全
common1 = [[Common alloc]init];
});
return common1;
}
NSLog(@"\n1:%p\n2:%p\n3:%p\n",[Common sharedInstanceOnce],[Common sharedInstanceOnce],[Common sharedInstanceOnce]);
1:0x600001c63870
2:0x600001c63870
3:0x600001c63870

end