(转)Objective-C的单例模式(singleton)
2012-02-06 17:47
274 查看
(转自:http://blog.csdn.net/arthurchenjs/article/details/6699598)
如果你准备写一个类,希望保证只有一个实例存在,同时可以得到这个特定实例提供服务的入口,那么可以使用单态设计模式。
单态模式在Java、C++中很常用,在Cocoa里,也可以实现。
但是,
Objective-C的单例模式绝对和你所想象不一样,他的写法和你所见过的所有语言的写法都不一样。
官方建议
由于自己设计单态模式存在一定风险,主要是考虑到可能在多线程情况下会出现的问题,因此苹果官方建议使用以下方式来实现单态模式:
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;
}
开源模板(附下载地址)
程序员都是偷懒的,现在流行使用一个宏定义来搞定这许多的事,而且考虑的更加周全。
单例包含以下接口
+ (MyClass*) sharedInstance;
+ (void) purgeSharedInstance;
调用sharedInstance会创建并返回单例
调用purgeSharedInstance会销毁单例
手动调用alloc也可以保证是单例,你可以这样调用
[[MyClass alloc] initWithParam:firstParam secondParam:secondParam];
只是要保证在sharedInstance之前调用,因为只有一次创建机会。
下面是使用宏的写法“
MyClass.h:
========================================
#import "SynthesizeSingleton.h"
@interface MyClass: SomeSuperclass
{
...
}
SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(MyClass);
@end
========================================
MyClass.m:
========================================
#import "MyClass.h"
@implementation MyClass
SYNTHESIZE_SINGLETON_FOR_CLASS(MyClass);
...
@end
========================================
下载地址
http://arthurchen.blog.51cto.com/attachment/201108/2483760_1313658868.rar
以上转载完毕。
----------------------------------分割线------------------------------------
以下是本人(xiaou)补充的:
上面下载地址下载下来的开源模板内容如下:(经本人在xcode4环境下验证修改了一两处compiled error)
文件名:SynthesizeSingleton.h
----------------------------------分割线------------------------------------
如果你准备写一个类,希望保证只有一个实例存在,同时可以得到这个特定实例提供服务的入口,那么可以使用单态设计模式。
单态模式在Java、C++中很常用,在Cocoa里,也可以实现。
但是,
Objective-C的单例模式绝对和你所想象不一样,他的写法和你所见过的所有语言的写法都不一样。
官方建议
由于自己设计单态模式存在一定风险,主要是考虑到可能在多线程情况下会出现的问题,因此苹果官方建议使用以下方式来实现单态模式:
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;
}
开源模板(附下载地址)
程序员都是偷懒的,现在流行使用一个宏定义来搞定这许多的事,而且考虑的更加周全。
单例包含以下接口
+ (MyClass*) sharedInstance;
+ (void) purgeSharedInstance;
调用sharedInstance会创建并返回单例
调用purgeSharedInstance会销毁单例
手动调用alloc也可以保证是单例,你可以这样调用
[[MyClass alloc] initWithParam:firstParam secondParam:secondParam];
只是要保证在sharedInstance之前调用,因为只有一次创建机会。
下面是使用宏的写法“
MyClass.h:
========================================
#import "SynthesizeSingleton.h"
@interface MyClass: SomeSuperclass
{
...
}
SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(MyClass);
@end
========================================
MyClass.m:
========================================
#import "MyClass.h"
@implementation MyClass
SYNTHESIZE_SINGLETON_FOR_CLASS(MyClass);
...
@end
========================================
下载地址
http://arthurchen.blog.51cto.com/attachment/201108/2483760_1313658868.rar
以上转载完毕。
----------------------------------分割线------------------------------------
以下是本人(xiaou)补充的:
上面下载地址下载下来的开源模板内容如下:(经本人在xcode4环境下验证修改了一两处compiled error)
文件名:SynthesizeSingleton.h
----------------------------------分割线------------------------------------
#ifndef SYNTHESIZE_SINGLETON_FOR_CLASS #import <objc/runtime.h> #pragma mark - #pragma mark Singleton /* Synthesize Singleton For Class * * Creates a singleton interface for the specified class with the following methods: * * + (MyClass*) sharedInstance; * + (void) purgeSharedInstance; * * Calling sharedInstance will instantiate the class and swizzle some methods to ensure * that only a single instance ever exists. * Calling purgeSharedInstance will destroy the shared instance and return the swizzled * methods to their former selves. * * * Usage: * * MyClass.h: * ======================================== * #import "SynthesizeSingleton.h" * * @interface MyClass: SomeSuperclass * { * ... * } * SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(MyClass); * * @end * ======================================== * * * MyClass.m: * ======================================== * #import "MyClass.h" * * @implementation MyClass * * SYNTHESIZE_SINGLETON_FOR_CLASS(MyClass); * * ... * * @end * ======================================== * * * Note: Calling alloc manually will also initialize the singleton, so you * can call a more complex init routine to initialize the singleton like so: * * [[MyClass alloc] initWithParam:firstParam secondParam:secondParam]; * * Just be sure to make such a call BEFORE you call "sharedInstance" in * your program. */ #define SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(__CLASSNAME__) \ \ + (__CLASSNAME__*) sharedInstance; \ + (void) purgeSharedInstance; #define SYNTHESIZE_SINGLETON_FOR_CLASS(__CLASSNAME__) \ \ static __CLASSNAME__* volatile _##__CLASSNAME__##_sharedInstance = nil; \ \ + (__CLASSNAME__*) sharedInstanceNoSynch \ { \ return (__CLASSNAME__*) _##__CLASSNAME__##_sharedInstance; \ } \ \ + (__CLASSNAME__*) sharedInstanceSynch \ { \ @synchronized(self) \ { \ if(nil == _##__CLASSNAME__##_sharedInstance) \ { \ _##__CLASSNAME__##_sharedInstance = [[self alloc] init]; \ } \ else \ { \ NSAssert2(1==0, @"SynthesizeSingleton: %@ ERROR: +(%@ *)sharedInstance method did not get swizzled.", self, self); \ } \ } \ return (__CLASSNAME__*) _##__CLASSNAME__##_sharedInstance; \ } \ \ + (__CLASSNAME__*) sharedInstance \ { \ return [self sharedInstanceSynch]; \ } \ \ + (id)allocWithZone:(NSZone*) zone \ { \ @synchronized(self) \ { \ if (nil == _##__CLASSNAME__##_sharedInstance) \ { \ _##__CLASSNAME__##_sharedInstance = [super allocWithZone:zone]; \ if(nil != _##__CLASSNAME__##_sharedInstance) \ { \ Method newSharedInstanceMethod = class_getClassMethod(self, @selector(sharedInstanceNoSynch)); \ method_setImplementation(class_getClassMethod(self, @selector(sharedInstance)), method_getImplementation(newSharedInstanceMethod)); \ method_setImplementation(class_getInstanceMethod(self, @selector(retainCount)), class_getMethodImplementation(self, @selector(retainCountDoNothing))); \ method_setImplementation(class_getInstanceMethod(self, @selector(release)), class_getMethodImplementation(self, @selector(releaseDoNothing))); \ method_setImplementation(class_getInstanceMethod(self, @selector(autorelease)), class_getMethodImplementation(self, @selector(autoreleaseDoNothing))); \ } \ } \ } \ return _##__CLASSNAME__##_sharedInstance; \ } \ \ + (void)purgeSharedInstance \ { \ @synchronized(self) \ { \ if(nil != _##__CLASSNAME__##_sharedInstance) \ { \ Method newSharedInstanceMethod = class_getClassMethod(self, @selector(sharedInstanceSynch)); \ method_setImplementation(class_getClassMethod(self, @selector(sharedInstance)), method_getImplementation(newSharedInstanceMethod)); \ method_setImplementation(class_getInstanceMethod(self, @selector(retainCount)), class_getMethodImplementation(self, @selector(retainCountDoSomething))); \ method_setImplementation(class_getInstanceMethod(self, @selector(release)), class_getMethodImplementation(self, @selector(releaseDoSomething))); \ method_setImplementation(class_getInstanceMethod(self, @selector(autorelease)), class_getMethodImplementation(self, @selector(autoreleaseDoSomething))); \ [_##__CLASSNAME__##_sharedInstance release]; \ _##__CLASSNAME__##_sharedInstance = nil; \ } \ } \ } \ \ - (id)copyWithZone:(NSZone *)zone \ { \ return self; \ } \ \ - (id)retain \ { \ return self; \ } \ \ - (NSUInteger)retainCount \ { \ NSAssert1(1==0, @"SynthesizeSingleton: %@ ERROR: -(NSUInteger)retainCount method did not get swizzled.", self); \ return NSUIntegerMax; \ } \ \ - (NSUInteger)retainCountDoNothing \ { \ return NSUIntegerMax; \ } \ - (NSUInteger)retainCountDoSomething \ { \ return [super retainCount]; \ } \ \ - (oneway void)release \ { \ NSAssert1(1==0, @"SynthesizeSingleton: %@ ERROR: -(void)release method did not get swizzled.", self); \ } \ \ - (void)releaseDoNothing{} \ \ - (void)releaseDoSomething \ { \ @synchronized(self) \ { \ [super release]; \ } \ } \ \ - (id)autorelease \ { \ NSAssert1(1==0, @"SynthesizeSingleton: %@ ERROR: -(id)autorelease method did not get swizzled.", self); \ return self; \ } \ \ - (id)autoreleaseDoNothing \ { \ return self; \ } \ \ - (id)autoreleaseDoSomething \ { \ return [super autorelease]; \ } #endif
相关文章推荐
- Objective —C 单例模式 Singleton
- objective-c中的Singleton单例模式的完整实现示例
- objective-c中的Singleton单例模式的完整实现示例
- objective-c中的Singleton单例模式的完整实现示例
- Objective —C 的单例模式 Singleton实现
- Objective-C的单例模式(singleton)
- Objective-C的单例模式(singleton)(转)
- Objective-C 单例模式singleton(参考apple官方例子)
- Objective-C的单例模式(singleton)(转)
- Objective-c 单例设计模式(Singleton)
- Swift、Objective-C 单例模式 (Singleton)
- Objective-C使用单例(Singleton)模式
- Objective-C设计模式——单例Singleton(对象创建)
- Swift、Objective-C 单例模式 (Singleton)
- objective-c中的Singleton单例模式的完整实现示例
- Objective-C的单例模式(singleton)
- Objective —C 的单例模式 Singleton实现
- Objective-C中的单例模式(singleton)
- objective_c 单例模式Singleton
- Objective-c 单例设计模式(Singleton)