单例模式可以说是每个应用都有用到的一个模式,在iOS的世界里更是常见。例如我们的UIApplication sharedApplicaiton应用的就是单利模式, defaultManager和defaultCenter等也是常见的单利。这也是为什么人们经常把CoreData的实例变量放在UIApplication里面。
对单例有了更清楚的了解以后,我们可以让我们的代码更加清晰。比如,我们可以把放在AppDelegate里的关于CoreData的代码移植到其他的单例类里面。
在相关网络博客上面看到了下面三种实现单利的方法。
1. 使用GCD实现单线程实现(给一篇参考文章http://bj007.blog.51cto.com/1701577/649413)
void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);其中第一个参数predicate,该参数是检查后面第二个参数所代表的代码块是否被调用的谓词,第二个参数则是在整个应用程序中只会被调用一次的代码块。dispach_once函数中的代码块只会被执行一次,而且还是线程安全。
@implementation MyClass
#pragma mark Singleton Methods
+ (id)sharedClass {
static MyClass *sharedMyClass = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyClass = [[self alloc] init];
});
return sharedMyClass;
}
@end
2. 加上同步
+ (id)sharedClass {
static MyClass *sharedMyClass = nil;
@synchronized(self) {
if (sharedMyClass == nil)
sharedMyClass = [[self alloc] init];
}
return sharedMyClass;
}
3. 没有ARC的同步实现(官网给出的也是这种方式 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32)
+ (id)sharedClass {
@synchronized(self) {
if(sharedMyClass == nil)
sharedMyClass = [[super allocWithZone:NULL] init];
}
return sharedMyClass;
}
+ (id)allocWithZone:(NSZone *)zone {
return [[self sharedMyClass] retain];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)retain {
return self;
}
- (unsigned)retainCount {
return UINT_MAX;
}
- (oneway void)release {
// never release
}
- (id)autorelease {
return self;
}
4. 其实还有其他的方式来实现。比如你将同步的代码快写到一个SynthesizeSingleton.h的头文件里。
#define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \
\
static classname *shared##classname = nil; \
\
+ (classname *)shared##classname \
{ \
@synchronized(self) \
{ \
if (shared##classname == nil) \
{ \
shared##classname = [[self alloc] init]; \
} \
} \
\
return shared##classname; \
} \
\
+ (id)allocWithZone:(NSZone *)zone \
{ \
@synchronized(self) \
{ \
if (shared##classname == nil) \
{ \
shared##classname = [super allocWithZone:zone]; \
return shared##classname; \
} \
} \
\
return nil; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return self; \
} \
\
在相关的类
@interface Preference : NSObject
+ (Preference *)sharedPreference;
在类的实现里加上
#import "SynthesizeSingleton.h"
@implementation Preference
SYNTHESIZE_SINGLETON_FOR_CLASS(Preference);
这种方式无疑是最简单也最易复用的方式。使用的时候直接调用shareXxx就可以了。
来源:oschina
链接:https://my.oschina.net/u/1047317/blog/146232