单例(单态)模式
单例设计模式确保对于一个给定的类只有一个实例存在,这个实例有一个全局惟一的访问点。它一般采用懒加载的方式在第一次用到实例的时候再去建立它。
注意:苹果大量使用了此模式。例如:[NSUserDefaults standardUserDefaults], [UIApplication sharedApplication], [UIScreen mainScreen], [NSFileManager defaultManager],全部的这些方法都返回一个单例对象。
你极可能会想为何这么关心是否一个类有多个实例?毕竟代码和内存都是廉价的,对吗?
有一些状况下,只有一个实例显得很是合理。举例来讲,你不须要有多个Logger的实例,除非你想去写多个日志文件。或者一个全局的配置处理类:实现线程安全的方式访问共享实例是容易的,好比一个配置文件,有好多个类同时修改这个文件。
如何使用单例模式
首先来看看下面的图:
上面的图描述了一个有单一属性(它就是单一实例)和sharedInstance,init两个方法的类。
客户端第一次发送sharedInstance消息的时候,instance属性还没有被初始化,因此此时你须要建立一个新的实例,而后返回它的引用。
当你下一次调用sharedInstance的时候,instance不须要任何初始化能够当即返回。这个逻辑保证老是只有一个实例。
你接下来将用这个模式来建立一个管理全部专辑数据的类。
你将注意到工程中有一个API的组,在这个组里你能够放入给你应用提供服务的全部类。在此组中,用IOS\Cocoa Touch\Objective-C class 模板建立一个新类,命名它为LibraryAPI,设置父类为NSObject.
打开LibraryAPI.h,用以下代码替换它的内容
- @interfaceLibraryAPI : NSObject
-
- + (LibraryAPI*)sharedInstance;
-
- @end
如今打开LibraryAPI.m,在@implementation 那一行后面插入下面的方法:
- + (LibraryAPI*)sharedInstance
- {
-
- static LibraryAPI *_sharedInstance = nil;
-
-
- static dispatch_once_t oncePredicate;
-
-
- dispatch_once(&oncePredicate, ^{
- _sharedInstance = [[LibraryAPI alloc] init];
- });
- return _sharedInstance;
- }
在这个简短的方法中,有一些须要须要注意的点:
1.声明一个静态变量去保存类的实例,确保它在类中的全局可用性。
2.声明一个静态变量dispatch_once_t ,它确保初始化器代码只执行一次
3.使用Grand Central Dispatch(GCD)执行初始化LibraryAPI变量的block.这 正是单例模式的关键:一旦类已经被初始化,初始化器永远不会再被调用。
下一次你调用sharedInstance的时候,dispatch_once块中的代码将不会执行(由于它已经被执行了一次),你将获得原先已经初始化好的实例。