1、概念理解
无论一个应用请求多少次,单例类都只会返回一个相同的实例。
一个典型(非单例)的类,可以用来创建许多需要用到的不同的实例,然而对于一个单例类来说,每个进程类别只能有一个实例,单例对象提供访问所有该单例类资源的接口。单例被用放在一个所有控制器可以获取的位置,例如各类型想获取一些通用的服务和资源。简单说就是,单例是用来实现在所有控制器中都可以获取的通用的服务和资源。
你可以通过一个工厂方法从单例类中得到全局实例,单例类会在第一次请求时通过懒加载的方式创建它唯一的实例并且确定在此后没有其他实例可以再被创建。一个单例类也应该阻止调用者对它的唯一实例做copy(复制),retain(引用计数加一),release(引用计数减一)操作,如果有必要你可以创建自己的单例类,例如,如果在应用中你有一个类需要去通知其他对象,你可以创建一个单例。
有几个Cocoa框架类是单例,包括
NSFileManager
, NSWorkspace
, 并且, 在 UIKit中, UIApplication
和 UIAccelerometer
.通过返回值获取实例的工厂方法的名字是有规范的,格式为 sharedClassType 例如,在Cocoa框架中获取实例的工厂方法名是
sharedFileManager
, sharedColorPanel
, and sharedWorkspace
.2、单例实现
方法一(不推荐):
static AccountManager *DefaultManager = nil;
+ (AccountManager *)defaultManager {
if (!DefaultManager)
DefaultManager = [[self allocWithZone:NULL] init];
return DefaultManager;
}
方法二:
+ (AccountManager *)sharedManager {
static AccountManager *sharedAccountManagerInstance = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedAccountManagerInstance = [[self alloc] init];
});
return sharedAccountManagerInstance;
}
方法二优点:
1. 保证线程安全。
2. 满足静态分析器的要求。
3. 兼容ARC
扩展:
关于 dispatch_once:
在整个程序的声明周期中,仅执行一次某一个block对象。
其他有需要只执行一次的操作也可以放到dispatch_once中执行。
注意:dispatch_once_t *predicate对象(用作断言的指针)必须是全局或者静态对象