ios之单例模式
原帖地址:http://www.galloway.me.uk/tutorials/singleton-classes/
本文为博主自行翻译,转载请注明出处:http://blog.csdn.net/iosevanhuang/article/details/13278323
“单例模式”是我在iOS中最常使用的设计模式之一。单例模式不需要传递任何参数,就有效地解决了不同代码间的数据共享问题。
背景
单例类是一个非常重要的概念,因为它们表现出了一种十分有用的设计模式。单例类的应用贯穿于整个iPhone SDK中。例如,UIApplication类有一个方法叫sharedApplication,从任何地方调用这个方法,都将返回与当前正在运行的应用 程序相关联的UIApplication实例。
博主补充:单例类保证了应用程序的生命周期中有且仅有一个该类的实例对象,而且易于外界访问。
实现
你可以用以下代码实现一个Objective-C的单例类(ARC模式下,非ARC模式下面会讲到):
1 2 3 4 5 6 7 8 9 10 11 |
#import <foundation/Foundation.h> @interface MyManager : NSObject { NSString *someProperty; } @property (nonatomic, retain) NSString *someProperty; + (id)sharedManager; @end |
MyManager.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#import "MyManager.h" @implementation MyManager @synthesize someProperty; #pragma mark Singleton Methods + (id)sharedManager { static MyManager *sharedMyManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedMyManager = [[self alloc] init]; }); return sharedMyManager; } - (id)init { if (self = [super init]) { someProperty = [[NSString alloc] initWithString:@"Default Property Value"]; } return self; } - (void)dealloc { // 永远不要调用这个方法 } @end |
MyManager.m
在这里我们定义了一个静态变量sharedMyManager,然后仅初始化一次该变量。这里使用了dispatch_once以保证该变量只被GCD初始化一次。操作系统将保证这是线程安全的。
如果不使用GCD,你可以使用以下代码:
1 2 3 4 5 6 7 8 |
+ (id)sharedManager { static MyManager *sharedMyManager = nil; @synchronized(self) { if (sharedMyManager == nil) sharedMyManager = [[self alloc] init]; } return sharedMyManager; } |
Non-GCD-based-code.m
接下来,当你需要使用这个单例对象时,你只要这样调用就可以了:
1 |
MyManager *sharedManager = [MyManager sharedManager]; |
snippet_file_0.m
我在我的代码中广泛使用单例类,比如创建一个单例类来处理CoreLocation或CoreData功能。
非ARC代码
虽然我并不那么推荐,但是如果你要使用非ARC环境的话,你应该使用以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#import "MyManager.h" static MyManager *sharedMyManager = nil; @implementation MyManager @synthesize someProperty; #pragma mark Singleton Methods + (id)sharedManager { @synchronized(self) { if(sharedMyManager == nil) sharedMyManager = [[super allocWithZone:NULL] init]; } return sharedMyManager; } + (id)allocWithZone:(NSZone *)zone { return [[self sharedManager] retain]; } - (id)copyWithZone:(NSZone *)zone { return self; } - (id)retain { return self; } - (unsigned)retainCount { return UINT_MAX; // 表示该对象永远不应被释放 } - (oneway void)release { // 从不释放 } - (id)autorelease { return self; } - (id)init { if (self = [super init]) { someProperty = [[NSString alloc] initWithString:@"Default Property Value"]; } return self; } - (void)dealloc { // 从不调用该方法 [someProperty release]; [super dealloc]; } @end |
MyManager-non-ARC.m
博主:这里的单例都是懒汉式单例,当单例对象的获取方法第一次被调用时创建单例对象。而在类被加载时就创建单例对象叫做饿汉式单例。