iOS中的單例設(shè)計模式

什么是單例模式?

單例模式是一種常用的軟件設(shè)計模式??梢员WC通過單例模式可以保證系統(tǒng)中一個類只有一個實(shí)例而且該實(shí)例易于外界訪問,從而方便對實(shí)例個數(shù)的控制并節(jié)約系統(tǒng)資源。

為什么要使用單例模式?

如果我們希望在系統(tǒng)中某個類的對象只能存在一個,單例模式是最好的解決方案。

怎么使用單例模式?

單例模式可以分為餓漢式懶漢式,在iOS中我們經(jīng)常使用的是懶漢式,下面我們看看怎么日常開發(fā)中怎么運(yùn)用單例模式。

  • 第一種寫法:

    + (id)sharedInstance {
        static testClass *sharedInstance = nil;
        
        // 為了在多線程中也保證只產(chǎn)生一個實(shí)例,加上線程同步鎖
        @synchronized(self) {
            if (!sharedInstance) {
                sharedInstance = [[self alloc] init];
            }
        }
        
        return sharedInstance;
    }
    
  • 第二種寫法:

    + (instancetype)shareTools
    {
        return [[self alloc] init];
    }
    
    + (instancetype)allocWithZone:(struct _NSZone *)zone
    {
        // 注意: 單例是不可以繼承的, 如果繼承引發(fā)問題
        // 如果先創(chuàng)建父類, 那么永遠(yuǎn)都是父類
        // 如果先創(chuàng)建子類, 那么永遠(yuǎn)都是子類
        static id instance = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = [super allocWithZone:zone];
        });
        return instance;
    }
    

注意:同時,我們還要重寫copyWithZone,mutableCopyWithZone和非ARC的方法release,retain,retainCount。

抽取單例宏

由于單例模式在我們的日常開發(fā)中使用頻率非常高,為了提高代碼的復(fù)用性,我們可以將單例模式的代碼抽取成一個宏,這樣以后使用的時候可以用宏快速實(shí)現(xiàn)單例模式。

將下面的代碼寫到Singleton.h文件中,以后用到單例的時候,直接將Singleton.h添加到項目中即可快速實(shí)現(xiàn)單例。

使用方法:在要實(shí)現(xiàn)單例類的.h文件聲明中寫下SingleInterface(*name*),.m文件中SingleImplementation(*name*),就實(shí)現(xiàn)了單例模式。

#define SingleInterface(name) +(instancetype)share##name

#if __has_feature(objc_arc)
// ARC
#define SingleImplementation(name)  +(instancetype)share##name \
{                                                               \
    return [[self alloc] init];                                 \
}                                                               \
static id _instance;                                            \
+ (instancetype)allocWithZone:(struct _NSZone *)zone            \
{                                                               \
    static dispatch_once_t onceToken;                           \
    dispatch_once(&onceToken, ^{                                \
        _instance = [super allocWithZone:zone];                 \
    });                                                         \
    return _instance;                                           \
}                                                               \
- (id)copyWithZone:(NSZone *)zone                               \
{                                                               \
    return self;                                                \
}                                                               \
- (id)mutableCopyWithZone:(NSZone *)zone                        \
{                                                               \
    return self;                                                \
}

#else

// MRC
#define SingleImplementation(name)  +(instancetype)share##name  \
{                                                               \
    return [[self alloc] init];                                 \
}                                                               \
static id _instance;                                            \
+ (instancetype)allocWithZone:(struct _NSZone *)zone            \
{                                                               \
    static dispatch_once_t onceToken;                           \
    dispatch_once(&onceToken, ^{                                \
        _instance = [super allocWithZone:zone];                 \
    });                                                         \
    return _instance;                                           \
}                                                               \
- (id)copyWithZone:(NSZone *)zone                               \
{                                                               \
    return self;                                                \
}                                                               \
- (id)mutableCopyWithZone:(NSZone *)zone                        \
{                                                               \
    return self;                                                \
}                                                               \
- (oneway void)release                                          \
{}                                                              \
- (instancetype)retain                                          \
{                                                               \
    return self;                                                \
}                                                               \
- (NSUInteger)retainCount                                       \
{                                                               \
    return MAXFLOAT;                                            \
}
#endif```
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 單例:意思就是只有一個實(shí)例。單例模式確保某一個類只有一個實(shí)例,而且自行實(shí)例化并向整個系統(tǒng)提供這個實(shí)例。這個類稱為單...
    CoderZS閱讀 639評論 1 13
  • 在開發(fā)中經(jīng)常會用到單例設(shè)計模式,目的就是為了在程序的整個生命周期內(nèi),只會創(chuàng)建一個類的實(shí)例對象,而且只要程序不被殺死...
    不要重名就好閱讀 596評論 0 0
  • 在開發(fā)中經(jīng)常會用到單例設(shè)計模式,目的就是為了在程序的整個生命周期內(nèi),只會創(chuàng)建一個類的實(shí)例對象,而且只要程序不被殺死...
    VincentHK閱讀 729評論 0 3
  • -1- 講真,我一點(diǎn)都不想來學(xué)校,為什么呢?因?yàn)槿思掖笏牧耍趺淳痛笏牧耍?我還不能接受這個現(xiàn)實(shí),仿佛昨天我還抱著...
    愛上世界的張大路閱讀 574評論 4 17
  • 片段一: 選自《堅持,一種可以養(yǎng)成的習(xí)慣》 R-原文片段 盡量找出不被侵犯的“圣地” 利用不容易被工作或私事影響的...
    笑語盈盈_8635閱讀 235評論 0 0

友情鏈接更多精彩內(nèi)容