單例模式和GCD單例實現(xiàn)

1、傳統(tǒng)單例模式
2、GCD單例模式
3、用宏實現(xiàn)GCD單例模式
4、用宏實現(xiàn)GCD單例模式,名稱隨類名變化而變化

單例模式一旦使用,將永遠不死。不管是控制器還是類,盡管push,pop還是dismiss都不會死掉,下一次用到時還是第一次創(chuàng)建的那個類。

1、看看傳統(tǒng)單例模式的實現(xiàn),要確保線程安全,一定要鎖起來。

// static 修飾的對象,只有在程序結(jié)束對才會被釋放
static id person;

/**
 創(chuàng)建單例的步驟
 1.保留一個單例對象的靜態(tài)實例
 2.聲明和實現(xiàn)一個類方法,返回一個有值的該類對象
 3.重寫allocWithZoon方法,做判空處理
 */

// 單例的類方法命名一般用share+當前類名
+ (instancetype)sharedPerson {
    
    // synchronized能保證里面的內(nèi)容同時只能被一個線程執(zhí)行
    @synchronized(self) {
        
        // 先判斷是否為空,如果為空再創(chuàng)建
        if (person == nil) {
            person = [[self alloc] init];
        }
    }
    
    return person;
}

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

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

2、看看GCD實現(xiàn),我們用的是once函數(shù),它已經(jīng)確保了線程安全問題

static Car *_car;

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

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

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

3、用宏實現(xiàn)GCD單例模式,當我們需要實現(xiàn)單例類時,其實代碼完全是一樣的,這樣我們抽成宏,但是這個我們只能用同一的方法,sharedInstance。如果我們想這樣,一個person類,那么單例就是sharedPerson,看第四份代碼。這里\作用是,讓宏識別到后面的代碼,因為宏默認只識別它后面一行代碼,加\就代表下一行也是

// .h文件
#define SingletonH  + (instancetype)sharedInstance;

// .m文件
#define SingletonM \
\
static id _instance;\
\
+ (instancetype)allocWithZone:(struct _NSZone *)zone {\
    \
    static dispatch_once_t onceToken;\
    dispatch_once(&onceToken, ^{\
        _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;\
}

4、用宏實現(xiàn)GCD單例模式,名稱隨類名變化而變化。這里需要注意,name都是傳過來的,所有在用時.h和.m都要傳name

像這樣
SingletonH(Car)
SingletonM(Car)

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

// .m文件
#define SingletonM(name) \
\
static id _instance;\
\
+ (instancetype)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:(NSZone *)zone {\
    return _instance;\
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容