1. 程式人生 > >Objective-C 中singleton(單例模式)的實現

Objective-C 中singleton(單例模式)的實現

OC中的單例很有意思,因為沒辦法像JAVA或C++中把建構函式設為private的來防止其它人直接 new 一個新物件,所以像如下單例的實現方式,只能祈禱大家必須按你要求的方式建立物件,有人不小心直接 [[ xx alloc] init] 建立一個物件,是很難發現的。

static SingletonClass *class = nil;

@implementation SingletonClass

+(SingletonClass*)sharedSingletonClass
{
    if (!class) {
        [[self alloc] init];
    }
    return class;
}

@end

其實為了防止別人通過其它方式建立物件,只要覆蓋+ (id)allocWithZone:(NSZone *)zone;方法就可以了,網上有多種實現版本,我自己綜合了一下自己實現了一個版本,用巨集做了一個封裝,程式碼如下:

#define DEFINE_SINGLETON_HEADER(className) \
\
+ (className *)shared##className;

#define DEFINE_SINGLETON_IMPLEMENTATION(className) \
\
static className *shared##className = nil; \
static dispatch_once_t pred; \
\
+ (className *)shared##className { \
    dispatch_once(&pred, ^{ \
        shared##className = [[super allocWithZone:NULL] init]; \
    }); \
    return shared##className; \
} \
\
+ (id)allocWithZone:(NSZone *)zone { \
    return [self shared##className];\
} \
\
- (id)copyWithZone:(NSZone *)zone { \
return self; \
}

實現單例程式碼如下:

@interface MySingleton : NSObject
DEFINE_SINGLETON_HEADER(MySingleton);
/**other method declare**/
@end
@implementation MySingleton
DEFINE_SINGLETON_IMPLEMENTATION(MySingleton)

- (instancetype)init {
    if (sharedMySingleton) {
        return sharedMySingleton;
    }
    if (self = [super init]) {
        //todo init other
    }
    return self;
}
@end

用這種方式很方便建立一個單例類,如果有一些極端情況沒考慮到,到時只需要直接更改巨集就可以了,不會影響到每個具體的單例類的實現。

參考網址:

http://www.cnblogs.com/supercheng/archive/2012/11/26/singlemodal.html

http://www.cnblogs.com/stoic/archive/2012/12/22/2940040.html