簡單說單例模式就是創(chuàng)建一個(gè)對(duì)象的全局唯一實(shí)體。方便管理全局?jǐn)?shù)據(jù)。具體單例模式的講解可以看設(shè)計(jì)模式相關(guān)書籍,這邊主要是介紹下現(xiàn)階段可以如何在Objective-C語言中實(shí)現(xiàn)單例模式。
如何實(shí)現(xiàn)
蘋果加入 GCD 之后我們可以利用 GCD實(shí)現(xiàn)。
MyManager.h
#import <foundation/Foundation.h>
@interface MyManager : NSObject {
NSString *someProperty;
}
@property (nonatomic, retain) NSString *someProperty;
+ (id)sharedManager;
@end
MyManager.m
#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 {
// Should never be called, but just here for clarity really.
}
@end
GCD 的 dispatch_once 能保證在多線程調(diào)用的時(shí)候 sharedMyManager 初始化一次。
如果不想使用 GCD來實(shí)現(xiàn),我們可以使用如下 :
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
@synchronized(self) {
if (sharedMyManager == nil)
sharedMyManager = [[self alloc] init];
}
return sharedMyManager;
}
Non-ARC (非 ARC 模式)
推薦如下實(shí)現(xiàn)方式
#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; //denotes an object that cannot be released
}
- (oneway void)release {
// never release
}
- (id)autorelease {
return self;
}
- (id)init {
if (self = [super init]) {
someProperty = [[NSString alloc] initWithString:@"Default Property Value"];
}
return self;
}
- (void)dealloc {
// Should never be called, but just here for clarity really.
[someProperty release];
[super dealloc];
}
@end