理解 单例模式

单例(单态)模式
单例设计模式确保对于一个给定的类只有一个实例存在,这个实例有一个全局唯一的访问点。它通常采用懒加载的方式在第一次用到实例的时候再去创建它。
 
注意:苹果大量使用了此模式。例如:[NSUserDefaults standardUserDefaults], [UIApplication sharedApplication], [UIScreen mainScreen], [NSFileManager defaultManager],所有的这些方法都返回一个单例对象。
 
你很可能会想为什么这么关心是否一个类有多个实例?毕竟代码和内存都是廉价的,对吗? 
 
有一些情况下,只有一个实例显得非常合理。举例来说,你不需要有多个Logger的实例,除非你想去写多个日志文件。或者一个全局的配置处理类:实现线程安全的方式访问共享实例是容易的,比如一个配置文件,有好多个类同时修改这个文件。
 
如何使用单例模式
首先来看看下面的图:
 
上面的图描述了一个有单一属性(它就是单一实例)和sharedInstance,init两个方法的类。
 
客户端第一次发送sharedInstance消息的时候,instance属性尚未被初始化,所以此时你需要创建一个新的实例,然后返回它的引用。
 
当你下一次调用sharedInstance的时候,instance不需要任何初始化可以立即返回。这个逻辑保证总是只有一个实例。
 
你接下来将用这个模式来创建一个管理所有专辑数据的类。
 
你将注意到工程中有一个API的组,在这个组里你可以放入给你应用提供服务的所有类。在此组中,用IOSCocoa TouchObjective-C class 模板创建一个新类,命名它为LibraryAPI,设置父类为NSObject.
 
打开LibraryAPI.h,用如下代码替换它的内容
  1. @interfaceLibraryAPI : NSObject   
  2.     
  3. + (LibraryAPI*)sharedInstance;   
  4.     
  5. @end   
 
现在打开LibraryAPI.m,在@implementation 那一行后面插入下面的方法:
  1. + (LibraryAPI*)sharedInstance   
  2. {   
  3.     // 1   
  4.     static LibraryAPI *_sharedInstance = nil;   
  5.     
  6.     // 2   
  7.     static dispatch_once_t oncePredicate;   
  8.     
  9.     // 3   
  10.     dispatch_once(&oncePredicate, ^{   
  11.         _sharedInstance = [[LibraryAPI alloc] init];   
  12.     });   
  13.     return _sharedInstance;   
  14. }   
在这个简短的方法中,有一些需要需要注意的点:
1.声明一个静态变量去保存类的实例,确保它在类中的全局可用性。
2.声明一个静态变量dispatch_once_t ,它确保初始化器代码只执行一次
3.使用Grand Central Dispatch(GCD)执行初始化LibraryAPI变量的block.这  正是单例模式的关键:一旦类已经被初始化,初始化器永远不会再被调用。
 
下一次你调用sharedInstance的时候,dispatch_once块中的代码将不会执行(因为它已经被执行了一次),你将得到原先已经初始化好的实例。 
 
注意: 为了学习更多关于GCD方面的信息以及如何使用,请查看本站指南Multithreading and Grand Central Dispatch 和 How to Use Blocks
 
原文地址:https://www.cnblogs.com/ygm900/p/3607146.html