单例的介绍
单例模式是在iOS开发中最常用的一种设计模式,单例模式可以让程序的各个模块共享数据,而不用去手动的去传递。所以单例类是一个我们要去理解的非常重要的模式,这种模式贯穿于iPhoneSDK中,例如UIApplication有一个方法叫做shareApplication用来共享当前程序的UIApplication实例。
单例的实现
添加一个ShareData类,在ShareData.h中声明如下:
#import <foundation/Foundation.h>
@interface ShareData : NSObject
{
NSString *string;
}
@property (nonatomic, retain) NSString *string;
+ (id)sharedData;
@end
在ShareData.m中实现该类:
#import "ShareData.h"
@implementation ShareData
@synthesize someProperty;
#pragma mark Singleton Methods
+ (id)sharedData
{
static ShareData *sharedData = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedData = [[self alloc] init];
});
return sharedData;
}
- (id)init
{
if (self = [super init])
{
self.string = [[[NSString alloc] initWithString:@"123"] autorelease];
}
return self;
}
- (void)dealloc
{
self.string = nil;
[super dealloc];
}
定义了一个在translation unit内全局唯一的静态变量shareData,通过调用静态方法shareData来初始化和获取变量。通过调用Grand Central Dispatch(GCD)的dispatch_once方法来保证静态变量只初始化一次,并且dispatch_once是系统保证的线程安全的。
在不用GCD的情况shareData方法的写法如下:
+ (id)sharedData
{
static ShareData *sharedData = nil;
@synchronized(self)
{
if (sharedData == nil)
{
sharedMyManager = [[self alloc] init];
}
}
return sharedData;
}
单例模式的使用如下:
ShareData *shareData = [ShareData sharedData];
在非
ARC(Automatic Reference Counting)下的实现代码如下:
#import "ShareData.h"
static ShareData *shareData = nil;
@implementation ShareData
@synthesize string;
#pragma mark Singleton Methods
+ (id)shareData
{
@synchronized(self)
{
if(shareData == nil)
{
shareData = [[super allocWithZone:NULL] init];
}
}
return shareData;
}
+ (id)allocWithZone:(NSZone *)zone
{
return [[self shareData] retain];
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (unsigned)retainCount
{
return UINT_MAX; //denotes an object that cannot be released
}
- (oneway void)release
{
// never release
}
- (id)autorelease
{
return self;
}
- (id)init
{
if (self = [super init])
{
string = [[NSString alloc] initWithString:@"123"];
}
return self;
}
- (void)dealloc
{
[string release];
[super dealloc];
}
@end