Creating a Singleton Instance
Some classes of the Foundation and AppKit frameworks create singleton objects. In a strict implementation, a singleton is the sole allowable instance of a class in the current process. But you can also have a more flexible singleton implementation in which a factory method always returns the same instance, but you can allocate and initialize additional instances.The NSFileManager class fits this latter pattern, whereas the UIApplication fits the former. When you ask for an instance of UIApplication, it passes you a reference to the sole instance, allocating and initializing it if it doesn’t yet exist.
A singleton object acts as a kind of control center, directing or coordinating the services of the class. Your class should generate a singleton instance rather than multiple instances when there is conceptually only one instance (as with, for example, NSWorkspace). You use singleton instances rather than factory methods or functions when it is conceivable that there might be multiple instances someday.
To create a singleton as the sole allowable instance of a class in the current process, you need to have an implementation similar to Listing 2-15. This code does the following:
It declares a static instance of your singleton object and initializes it to nil.
In your class factory method for the class (named something like “sharedInstance” or “sharedManager”), it generates an instance of the class but only if the static instance is nil.
It overrides the allocWithZone: method to ensure that another instance is not allocated if someone tries to allocate and initialize an instance of your class directly instead of using the class factory method. Instead, it just returns the shared object.
It implements the base protocol methods copyWithZone:, release, retain, retainCount, and autorelease to do the appropriate things to ensure singleton status. (The last four of these methods apply to memory-managed code, not to garbage-collected code.)
创建单例实例
Foundation和AppKit框架的某些类创建单例对象。在严格的实现中,单例是当前进程中类的唯一允许实例。但是您也可以使用更灵活的单例实现,其中工厂方法始终返回相同的实例,但您可以分配和初始化其他实例.NSFileManager类适合后一种模式,而UIApplication适合前者。当您要求UIApplication的实例时,它会向您传递对唯一实例的引用,如果它尚不存在则分配并初始化它。
单例对象充当一种控制中心,指导或协调该类的服务。当概念上只有一个实例时(例如,NSWorkspace),您的类应该生成单例实例而不是多个实例。当可以想象某天可能存在多个实例时,您可以使用单例实例而不是工厂方法或函数。
要在当前进程中创建单例作为类的唯一允许实例,您需要具有类似于清单2-15的实现。此代码执行以下操作:
它声明了一个单例对象的静态实例,并将其初始化为nil。
在类的类工厂方法(命名为“sharedInstance”或“sharedManager”)中,它生成类的实例,但仅在静态实例为nil时生成。
它会覆盖allocWithZone:方法,以确保在有人尝试直接分配和初始化类的实例而不是使用类工厂方法时,不会分配另一个实例。相反,它只返回共享对象。
它实现了基本协议方法copyWithZone:,release,retain,retainCount和autorelease来做相应的事情以确保单例状态。 (这些方法的最后四个适用于内存管理代码,而不适用于垃圾收集代码。)
static MyGizmoClass *sharedGizmoManager = nil;
+ (MyGizmoClass*)sharedManager
{
if (sharedGizmoManager == nil) {
sharedGizmoManager = [[super allocWithZone:NULL] init];
}
return sharedGizmoManager;
}
+ (id)allocWithZone:(NSZone *)zone
{
return [[self sharedManager] retain];
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (NSUInteger)retainCount
{
return NSUIntegerMax; //denotes an object that cannot be released
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
If you want a singleton instance (created and controlled by the class factory method) but also have the ability to create other instances as needed through allocation and initialization, do not override allocWithZone: and the other methods following it as shown in Listing 2-15.
如果您需要单例实例(由类工厂方法创建和控制),但也能够通过分配和初始化根据需要创建其他实例,请不要覆盖allocWithZone:以及其后的其他方法,代码如上所示。
网友评论