转载

iOS单例模式(面试必考)

# 单例模式(面试必考)

1. 单例模式的作用

  • 可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问
  • 从而方便地控制了实例个数,并节约系统资源

2. 单例模式的使用场合

  • 在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次)

3. ARC中,单例模式的实现

  • 1.在.m中保留一个全局的static的实例

    static id _instance;
  • 2.重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全)

+ (instancetype)allocWithZone:(struct _NSZone *)zone {     static dispatch_once_t onceToken;     dispatch_once(&onceToken, ^{         _instance = [super allocWithZone:zone];     });     return _instance; }
  • 3.提供1个类方法让外界访问唯一的实例
+ (instancetype)sharedInstance {     static dispatch_once_t onceToken;     dispatch_once(&onceToken, ^{         _instance = [[self alloc] init];     });     return _instance; }
  • 4.实现copyWithZone:方法
- (id)copyWithZone:(struct _NSZone *)zone {     return _instance; }

4.ARC中完整版(GCD)

static id _instance; + (instancetype)allocWithZone:(struct _NSZone *)zone {  static dispatch_once_t onceToken;  dispatch_once(&onceToken, ^{   _instance = [[super allocWithZone:zone] init]; // 记住这儿是super,不能用self  });  return _instance; } + (instancetype)sharedPerson {  static dispatch_once_t onceToken;  dispatch_once(&onceToken, ^{   _instance = [[self alloc] init];  });  return _instance; } // copyWithZone方法的前提是必须先有一个对象 - (id)copyWithZone:(NSZone *)zone {  return _instance; }  
  • 在实际开发中,一个应用程序可能有多个对象是单例对象,此时我们应该把 单例抽成一个宏放在一个单独的.h文件中 , 千万不能用继承

    • 其中 / 表示此行跟下面一行是一起的
    • ## 表示后面是参数
    • 此时,注释只能在上面,在右边注释会报错的
// .h文件中的声明 #define SLInstanceH(name)  + (instancetype)shared##name; // .m文件的实现 #define SLInstanceM(name) static id _instance; / / + (instancetype)allocWithZone:(struct _NSZone *)zone/ {/  static dispatch_once_t onceToken;/  dispatch_once(&onceToken, ^{/   _instance = [[super allocWithZone:zone] init];/  });/  return _instance;/ }/ / + (instancetype)shared##name/ {/  static dispatch_once_t onceToken;/  dispatch_once(&onceToken, ^{/   _instance = [[self alloc] init];/  });/  return _instance;/ }/ / - (id)copyWithZone:(NSZone *)zone/ {/  return _instance;/ } 
  • 使用宏的时候
  • 在.m文件中
#import <Foundation/Foundation.h> #import "SLSharedInstance.h"  // 导入,定义了宏的.h文件  @interface SLPerson : NSObject<NSCopying> SLInstanceH(Person)  // 传入单例的对象 @end
  • 在.h文件中
#import "SLPerson.h"  @implementation SLPerson SLInstanceM(Person) @end

5. 单例模式(常规做法,非GCD)

  • 一定要加互斥锁,不然会有线程安全问题
#import "SLPerson.h" @implementation SLPerson static id _instance; + (instancetype)allocWithZone:(struct _NSZone *)zone {  @synchronized(self){ // 一定要加互斥锁,不然会有线程安全问题   if (_instance == nil) {    _instance = [[super allocWithZone:zone] init];   }  }  return _instance; } + (instancetype)sharedPerson {  @synchronized(self){   if (_instance == nil) {    _instance = [[self alloc] init];   }  }  return _instance; } // 要有对象才能进行copy - (id)copyWithZone:(NSZone *)zone {  return _instance; } @end 
正文到此结束
Loading...