iOS之單例模式

單例模式

  • 1.1 概念相關(guān)

(1)單例模式

在程序運行過程,一個類只有一個實例

(2)使用場合

在整個應(yīng)用程序中,共享一份資源(這份資源只需要創(chuàng)建初始化1次)
  • 1.2 ARC實現(xiàn)單例

(1)步驟

01 在類的內(nèi)部提供一個static修飾的全局變量
02 提供一個類方法,方便外界訪問
03 重寫+allocWithZone方法,保證永遠(yuǎn)都只為單例對象分配一次內(nèi)存空間
04 嚴(yán)謹(jǐn)起見,重寫-copyWithZone方法和-MutableCopyWithZone方法

(2)相關(guān)代碼

//提供一個static修飾的全局變量,強(qiáng)引用著已經(jīng)實例化的單例對象實例
static XMGTools *_instance;

//類方法,返回一個單例對象
+(instancetype)shareTools
{
     //注意:這里建議使用self,而不是直接使用類名Tools(考慮繼承)

    return [[self alloc]init];
}

//保證永遠(yuǎn)只分配一次存儲空間
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
    //使用GCD中的一次性代碼
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        _instance = [super allocWithZone:zone];
//    });

    //使用加鎖的方式,保證只分配一次存儲空間
    @synchronized(self) {
        if (_instance == nil) {
            _instance = [super allocWithZone:zone];
        }
    }
    return _instance;
}
/*
1. mutableCopy 創(chuàng)建一個新的可變對象,并初始化為原對象的值,新對象的引用計數(shù)為 1;
2. copy 返回一個不可變對象。分兩種情況:(1)若原對象是不可變對象,那么返回原對象,并將其引用計數(shù)加 1 ;(2)若原對象是可變對象,那么創(chuàng)建一個新的不可變對象,并初始化為原對象的值,新對象的引用計數(shù)為 1。
*/
//讓代碼更加的嚴(yán)謹(jǐn)
-(nonnull id)copyWithZone:(nullable NSZone *)zone
{
//    return [[self class] allocWithZone:zone];
    return _instance;
}

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

  • 1.3 MRC實現(xiàn)單例

(1)實現(xiàn)步驟

01 在類的內(nèi)部提供一個static修飾的全局變量
02 提供一個類方法,方便外界訪問
03 重寫+allocWithZone方法,保證永遠(yuǎn)都只為單例對象分配一次內(nèi)存空間
04 嚴(yán)謹(jǐn)起見,重寫-copyWithZone方法和-MutableCopyWithZone方法
05 重寫release方法
06 重寫retain方法
07 建議在retainCount方法中返回一個最大值

(2)配置MRC環(huán)境知識

01 注意ARC不是垃圾回收機(jī)制,是編譯器特性
02 配置MRC環(huán)境:build setting ->搜索automatic ref->修改為NO

(3)相關(guān)代碼

//提供一個static修飾的全局變量,強(qiáng)引用著已經(jīng)實例化的單例對象實例
static XMGTools *_instance;

//類方法,返回一個單例對象
+(instancetype)shareTools
{
     //注意:這里建議使用self,而不是直接使用類名Tools(考慮繼承)

    return [[self alloc]init];
}

//保證永遠(yuǎn)只分配一次存儲空間
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
    //使用GCD中的一次性代碼
//    static dispatch_once_t onceToken;
//    dispatch_once(&onceToken, ^{
//        _instance = [super allocWithZone:zone];
//    });

    //使用加鎖的方式,保證只分配一次存儲空間
    @synchronized(self) {
        if (_instance == nil) {
            _instance = [super allocWithZone:zone];
        }
    }
    return _instance;
}

//讓代碼更加的嚴(yán)謹(jǐn)
-(nonnull id)copyWithZone:(nullable NSZone *)zone
{
//    return [[self class] allocWithZone:zone];
    return _instance;
}

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

//在MRC環(huán)境下,如果用戶retain了一次,那么直接返回instance變量,不對引用計數(shù)器+1
//如果用戶release了一次,那么什么都不做,因為單例模式在整個程序運行過程中都擁有且只有一份,程序退出之后被釋放,所以不需要對引用計數(shù)器操作
-(oneway void)release
{
}

-(instancetype)retain
{
    return _instance;
}

//慣用法,有經(jīng)驗的程序員通過打印retainCount這個值可以猜到這是一個單例
-(NSUInteger)retainCount
{
    return MAXFLOAT;
}

  • 1.4 通用版本

(1)有意思的對話

01 問:寫一份單例代碼在ARC和MRC環(huán)境下都適用?
答:可以使用條件編譯來判斷當(dāng)前項目環(huán)境是ARC還是MRC
02 問:條件編譯的代碼呢,么么噠?
//答:條件編譯
#if __has_feature(objc_arc)
//如果是ARC,那么就執(zhí)行這里的代碼1
#else
//如果不是ARC,那么就執(zhí)行代理的代碼2
#endif
03 問:在項目里面往往需要實現(xiàn)很多的單例,比如下載、網(wǎng)絡(luò)請求、音樂播放等等,弱弱的問一句單例可以用繼承嗎?
答:單例是不可以用繼承的,如果想一次寫就,四處使用,那么推薦親使用帶參數(shù)的宏定義啦!
04 問:宏定義怎么弄?
答:這個嘛~~回頭看一眼我的代碼咯,親。

(2)使用帶參數(shù)的宏完成通用版單例模式代碼

01 注意條件編譯的代碼不能包含在宏定義里面
02 宏定義的代碼只需要寫一次就好,之后直接拖到項目中用就OK

一些單例:
1、UIApplication(應(yīng)用程序?qū)嵗?
獲取方式:[UIApplication sharedApplication]
詳細(xì):http://www.cnblogs.com/hissia/p/5678518.html

2、NSNotificationCenter(消息中心)
獲取方式:[NSNotificationCenter defaultCenter]
常用的通知模式

3、NSFileManager(文件管理)
獲取方式:[NSFileManager defaultManager]

4、NSUserDefaults(偏好設(shè)置)
獲取方式:[NSUserDefaults standardUserDefaults]
詳細(xì):http://www.cnblogs.com/hissia/p/5642405.html

5、NSURLCache(請求緩存)
獲取方式:[NSURLCache sharedURLCache]

6、NSHTTPCookieStorage(應(yīng)用程序cookies池)
獲取方式:[NSHTTPCookieStorage sharedHTTPCookieStorage]

7、NSURLSession(發(fā)送請求時候用的)
獲取方式:[NSURLSession sharedSession]

8、UIMenuController(彈出的菜單可以選擇,復(fù)制,剪切,粘貼的功能)
獲取方式:[UIMenuController sharedMenuController]

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

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

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