iOS 设计模式(三)-单例模式

1.简介

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

系统提供的单例类:

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

一般在程序中,经常调用的类,如工具类、公共跳转类等,都会采用单例模式;

2.单例类的生命周期

iOS内存管理5大分区:

位置 存放的变量
临时变量(由编译器管理自动创建/分配/释放的,栈中的内存被调用时处于存储空间中,调用完毕后由系统系统自动释放内存)
通过alloc、calloc、malloc或new申请内存,由开发者手动在调用之后通过free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存,在ARC模式下,由系统自动管理。
全局区域 静态变量(编译时分配,APP结束时由系统释放)
常量 常量(编译时分配,APP结束时由系统释放)
代码区 存放代码

在程序中,一个单例类在程序中只能初始化一次,为了保证在使用中始终都是存在的,所以单例是在存储器的全局区域,在编译时分配内存,只要程序还在运行就会一直占用内存,在APP结束后由系统释放这部分内存。

3.单例类实现

实现单例有几种方式:

  • 同步锁 NSLock
  • @synchronized(self) {}
  • 信号量控制并发 dispatch_semaphore_t
  • 条件锁 NSConditionLock
  • dispatch_once_t
    考虑数据和线程问题,苹果官方推荐开发者使用 dispatch_once_t 来创建单例。
#import 
NS_ASSUME_NONNULL_BEGIN

@interface DJTestModel : NSObject
+ (instancetype)shareInstance;
@end

NS_ASSUME_NONNULL_END
#import "DJTestModel.h"
@implementation DJTestModel
static DJTestModel *instance;
+ (id)allocWithZone:(struct _NSZone *)zone{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super allocWithZone:zone];
    });
    return instance;
}
+ (instancetype)shareInstance{
    return [[self alloc] init];
}
@end
4.单例的优缺点

优点:
(1)在整个程序中只会实例化一次,所以在程序如果出了问题,可以快速的定位问题所在;
(2)由于在整个程序中只存在一个对象,节省了系统内存资源,提高了程序的运行效率;

缺点:
(1)不能被继承,不能有子类;
(2)不易被重写或扩展(可以使用分类);
(3)同时,由于单例对象只要程序在运行中就会一直占用系统内存,该对象在闲置时并不能销毁,在闲置时也消耗了系统内存资源;

你可能感兴趣的:(iOS 设计模式(三)-单例模式)