ios 單例實現方式

在開發中經常會用到單例,它在整個程序的運行週期裏面只會被創建一次,只要程序沒有結束,它就不會被釋放!創建單例的兩種方式如下:

一、GCD方式創建單例

static id _instance;

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToke;
    dispatch_once(&onceToke, ^{
        
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

+ (instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
       
        _instance = [[self alloc] init];
    });
    return _instance;
}

- (id)copyWithZone:(NSZone *)zone
{
    return _instance;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
    return _instance;
}


二、互鎖創建單例的方法

static id _instance;

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    @synchronized(self) {
        if (_instance == nil) {
            _instance = [super allocWithZone:zone];
        }
    }
    return _instance;
}

+ (instancetype)sharedInstance
{
    @synchronized(self) {
        if (_instance == nil) {
            _instance = [[self alloc] init];
        }
    }
    return _instance;
}

- (id)copyWithZone:(NSZone *)zone
{
    return _instance;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
    return _instance;
}

說明

1、CGD創建單例的方式中,用dispatch_once保證了裏面的代碼只能被執行一次,如果程序再次走到這個方法的時候會直接返回創建好的實例對象,這樣保證了只會創建一個實例對象;

2、 在互鎖創建單例的方式中,@synchronized相當於給括起來的任務加了一把鎖,如果當前任務正在執行,另外一條線程執行到@synchronized時候就會進入睡眠模式,等當前任務執行完後纔會執行,此時_instance已經被創建,不爲nil,所以直接返回_instance,這樣也保證了只會創建一個實例對象。但是在多線程開發中,這種方式會影響程序的性能,建議用第一種


總結

在多線程開發中互鎖的方式會影響項目的性能,建議用GCD的方式!


通過GCD創建單例的方式是固定不變的,爲了方便以後快速實現單例,可以把創建方式定義成宏。

// .h文件
#define singleton_h(name) + (instancetype)shared##name;

// .m文件
#define singleton_m(name) \
static id _instance; \
+ (id)allocWithZone:(struct _NSZone *)zone \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [super allocWithZone:zone]; \
}); \
return _instance; \
} \
\
+ (instancetype)shared##name \
{ \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
_instance = [[self alloc] init]; \
}); \
return _instance; \
} \
\
+ (id)copyWithZone:(struct _NSZone *)zone \
{ \
return _instance; \
}\
\
- (id)mutableCopyWithZone:(NSZone *)zone\
{\
    return _instance;\
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章