iOS—单例模式

什么是单例模式?

一个单例类,在整个程序中只有一个实例,并且提供一个类方法供全局调用,在编译时初始化这个类,然后一直保存在内存中,到程序(APP)退出时由系统自动释放这部分内存。

系统提供的单例类
UIApplication(应用程序实例类)
NSNotificationCenter(消息中心类)
NSFileManager(文件管理类)
NSUserDefaults(应用程序设置)
NSURLCache(请求缓存类)
NSHTTPCookieStorage(应用程序cookies池)

什么时候选择单例模式?

一个类只有一个实例对象时

如何实现?

需要补充的点
dispatch_once 无论使用多线程还是单线程,都只执行一次, 在安全的前提下也保证了性能, 是官方推荐的实现单例方式.

  • dispatch_once 主要是根据onceToken 的值来决定怎么去执行代码。
    1.当onceToken=0时,线程执行dispatch_once的block中代码
    2.当onceToken=-1时,线程跳过dispatch_once的block中代码不执行
    3.当onceToken为其他值时,线程被阻塞,等待onceToken值改变
  • dispatch_once 执行的流程
    1.当线程调用shareInstance,此时onceToken = 0,调用block中的代码。 此时onceToken的值变为其他值。
    2.当其他线程再调用shareInstance方法时,onceToken的值已经是其他值了,线程阻塞。
    3.当block线程执行完block之后,onceToken变为-1.其他线程不再阻塞,跳过block。
    4.下次再调用shareInstance时,block已经为-1.直接跳过block。
  • 创建一个类,继承于NSObject
    声明一个类方法,允许程序通过该方法获取该类的唯一实例。
    但如果是用alloc、copy方法依然会创建多个实例。
    在对象创建的时候,无论是alloc还是new,都会调用到 allocWithZone方法。在通过拷贝的时候创建对象时,会调用到-(id)copyWithZone:(NSZone *)zone,-(id)mutableCopyWithZone:(NSZone *)zone方法。因此,可以重写这些方法,让创建的对象唯一。

@interface Singleton : NSObject

+ (Singleton *)shareInstance;

@end

#import "Singleton.h"

@implementation Singleton

static Singleton *singleton = nil;

+ (Singleton *)shareInstance {

    static dispatch_once_t oncetoken;
    dispatch_once(&oncetoken, ^{
        singleton = [[super allocWithZone:nil] init];
    });
    return singleton;
}

+ (id)allocWithZone:(struct _NSZone *)zone {
    return singleton;
}

- (id)copyWithZone:(NSZone *)zone{
	return singleton;
}

- (id)mutableCopyWithZone:(NSZone *)zone{
    return singleton;
}

@end


创建一个实例,使用alloc、copy等方法,打印查看地址

#import "ViewController.h"
#import "Singleton.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    Singleton *a = [Singleton shareInstance];
    Singleton *b = [Singleton shareInstance];
    Singleton *c = [[Singleton alloc] init];
    Singleton *d = [a copy];
    Singleton *e = [b mutableCopy];
    NSLog(@"%@, %@, %@, %@, %@", a, b, c, d, e);
    
}

@end

打印结果如下:
1

参考文章:
http://www.cocoachina.com/articles/21300
https://www.jianshu.com/p/9165a6de227e

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值