Foundation和Application Kit框架中的一些类只允许创建单件对象,即这些类在当前进程中的唯一实例。举例来说,
NSFileManager
和NSWorkspace
类在使用时都是基于进程进行单件对象的实例化。当您向这些类请求实例的时候,它们会向您传递单一实例的一个引用,如果该实例还不存在,则首先进行实例的分配和初始化。
单件对象充当控制中心的角色,负责指引或协调类的各种服务。如果您的类在概念上只有一个实例(比如NSWorkspace
),就应该产生一个单件实例,而不是多个实例;如果将来某一天可能有多个实例,您可以使用单件实例机制,而不是工厂方法或函数。
创建单件实例时,您需要在代码中执行下面的工作:
-
声明一个单件对象的静态实例,并初始化为
nil
。 -
在该类的类工厂方法(名称类似于“sharedInstance”或“sharedManager”)中生成该类的一个实例,但仅当静态实例为
nil
的时候。 -
重载
allocWithZone:
方法,确保当用户试图直接(而不是通过类工厂方法)分配或初始化类的实例时,不会分配出另一个对象。 -
实现基本协议方法:
copyWithZone:
、release
、retain
、retainCount
、和autorelease
,以保证单件的状态。
列表2-15 显示如何实现一个单件:
- <span xmlns="http://www.w3.org/1999/xhtml" style="">static MyGizmoClass *sharedGizmoManager = nil;
- + (MyGizmoClass*)sharedManager
- {
- @synchronized(self) {
- if (sharedGizmoManager == nil) {
- [[self alloc] init]; // assignment not done here
- }
- }
- return sharedGizmoManager;
- }
- + (id)allocWithZone:(NSZone *)zone
- {
- @synchronized(self) {
- if (sharedGizmoManager == nil) {
- sharedGizmoManager = [super allocWithZone:zone];
- return sharedGizmoManager; // assignment and return on first allocation
- }
- }
- return nil; //on subsequent allocation attempts return nil
- }
- - (id)copyWithZone:(NSZone *)zone
- {
- return self;
- }
- - (id)retain
- {
- return self;
- }
- - (unsigned)retainCount
- {
- return UINT_MAX; //denotes an object that cannot be released
- }
- - (void)release
- {
- //do nothing
- }
- - (id)autorelease
- {
- return self;
- }</span>
当您需要一个单件实例(由类工厂方法来创建和控制),又需要通过分配和初始化创建其它实例时,就可能出现问题。在这种情况下,您不必重载allocWithZone:
及其后的其它方法