單例模式(Singleton)

定義:

單例模式使用場景,必須一個類只有一個實例,并且提供一個訪問它的全局訪問點。
單例模式的要點有三個;一是某個類只能有一個實例;二是它必須自行創(chuàng)建這個實例;三是它必須自行向整個系統(tǒng)提供這個實例。
從具體實現(xiàn)角度來說,就是以下三點:一是單例模式的類只提供私有的構造函數,二是類定義中含有一個該類的靜態(tài)私有對象,三是該類提供了一個靜態(tài)的公有的函數用于創(chuàng)建或獲取它本身的靜態(tài)私有對象
在 Cocoa Touch中 比較代表的就是 UIApplication ---[UIApplication sharedApplication]。

下面我們來思考幾個問題

1、我們?yōu)槭裁匆脤嵗龑ο蠖皇穷悓ο螅?br> OC的類對象可以接受消息,也可以在其他對象中調用,而且runtime確保類在application生命周期內只初始化一次。
答案是:因為增加維護成本。(已經存在一個類,你想寫個子類去實現(xiàn)同樣的事情。首先使用的是類方法調用,那么你得替換所有的方法調用類名稱)。
注意我們應該盡量避免硬編碼類名,這樣增加了將來維護的難度
解決方法:使用一個全局變量 存儲使用的指針。

2、 那么直接使用全局變量的指針 是不是就完美了呢?
答案是:否。靜態(tài)的全局變量,和對象的實例變量 比起來維護性太差。不具有面向對象的可以繼承的能力。方法和變量也不具有多態(tài)的好處。

嚴謹的單例的創(chuàng)建:

static Singleton *_sharedSingleton = nil;

@implementation Singleton

- (instancetype)init {
    [NSException raise:@"SingletonPattern"
                format:@"Cannot instantiate singleton using init method, sharedInstance must be used."];
    return nil;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
     if (self != [Singleton class]) {
        [NSException raise:@"SingletonPattern"
                    format:@"Cannot use sharedInstance method from subclass."];
    }
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedSingleton = [[Singleton alloc] initInstance];
    });
    return _sharedSingleton;
}

+ (instancetype)new {
    return [self alloc]; 
}

- (instancetype)copyWithZone:(NSZone *)zone {
    return _sharedSingleton;
}

- (instancetype)mutableCopyWithZone:(NSZone *)zone {
    return [self copyWithZone:zone];
}

+ (Singleton *)sharedInstance {
    if (self != [Singleton class]) {
        [NSException raise:@"SingletonPattern"
                    format:@"Cannot use sharedInstance method from subclass."];
    }
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedSingleton = [[Singleton alloc] initInstance];
    });
    return _sharedSingleton;
}

#pragma mark - private method

- (instancetype)initInstance {
    return [super init];
}

@end

最后:

只有當一個類表示真正應該存在一次時,才使它成為單例。有些時候,最初看起來符合這個標準的東西將不再適合應用程序的發(fā)展。例如,有多個類型需求,或者是不是生命周期只存在一次。在這種情況下單例方法不再適用。通常,我們會使用manger的管理方式。例如NSFileManager。接下來介紹manger管理方式。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容