單例里你不知道的事兒

一位開發(fā)前輩玉令天下的博客里對(duì)單例的介紹很不錯(cuò)澜驮,原文iOS的單例模式在這里作兩點(diǎn)補(bǔ)充昭雌。

  • 即使用GCD的dispatch_once 創(chuàng)建的單例图毕,最好還是遵循<NSCopying,NSMutableCopying>的協(xié)議盹舞,并實(shí)現(xiàn)相應(yīng)的方法叙量,防止別人誤調(diào)copy方法而崩潰

在這里我寫了個(gè)demo
Singleton.h文件如下

#import <Foundation/Foundation.h>

@interface Singleton : NSObject

+(instancetype) shareInstance;

@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *title;

@end

Singleton.m文件如下

#import "Singleton.h"

@interface Singleton () <NSCopying,NSMutableCopying>

@end

@implementation Singleton

static Singleton* _instance = nil;

+(instancetype) shareInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:NULL] init];//調(diào)用[[super allocWithZone:NULL] init],因?yàn)楸绢愐呀?jīng)重載allocWithZone基本的對(duì)象分配方法,要借用父類(NSObject)的功能來幫助處理底層內(nèi)存分配
        _instance.name = @"";
        _instance.title = @"";
    });
    
    return _instance;
}

+(id)allocWithZone:(struct _NSZone *)zone {
//    return [Singleton shareInstance];
    return _instance;//兩種寫法效果是一樣的
}

- (id)copyWithZone:(nullable NSZone *)zone {
//    return [Singleton shareInstance];
    return _instance;
}

- (id)mutableCopyWithZone:(nullable NSZone *)zone {
//    return [Singleton shareInstance];
    return _instance;
}

- (NSString *)description {
    return [NSString stringWithFormat:@"_name====%@,_title=====%@",_name,_title];
}

測(cè)試方法如下

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    Singleton *singleton = [Singleton shareInstance];
    singleton.name = @"singleton";
    singleton.title = @"singletonDesc";
    NSLog(@"singleton------%p,description------%@",singleton,singleton);
    
    Singleton *singletonCopy = [singleton copy];
    NSLog(@"singletonCopy------%p,description------%@",singletonCopy,singletonCopy);
    
    Singleton *singletonMutableCopy = [singleton mutableCopy];
    NSLog(@"singletonMutableCopy------%p,description------%@",singletonMutableCopy,singletonMutableCopy);
    
    Singleton *singletonShareInstanceAgain = [Singleton shareInstance];
    NSLog(@"singletonShareInstanceAgain------%p,singletonShareInstanceAgain------%@",singletonShareInstanceAgain,singletonShareInstanceAgain);

    Singleton *singletonAlloc = [[Singleton alloc] init];
    NSLog(@"singletonAlloc------%p,description------%@",singletonAlloc,singletonAlloc);
}

打印結(jié)果如下

2018-08-15 15:00:31.441223+0800 SingletonTest[65282:7781841] singleton------0x60400042c800,description------_name====singleton,_title=====singletonDesc
2018-08-15 15:00:31.441499+0800 SingletonTest[65282:7781841] singletonCopy------0x60400042c800,description------_name====singleton,_title=====singletonDesc
2018-08-15 15:00:31.441726+0800 SingletonTest[65282:7781841] singletonMutableCopy------0x60400042c800,description------_name====singleton,_title=====singletonDesc
2018-08-15 15:00:31.441855+0800 SingletonTest[65282:7781841] singletonShareInstanceAgain------0x60400042c800,singletonShareInstanceAgain------_name====singleton,_title=====singletonDesc
2018-08-15 15:00:31.442457+0800 SingletonTest[65282:7781841] singletonAlloc------0x60400042c800,description------_name====singleton,_title=====singletonDesc

可以看出shareInstance倡蝙、copy、mutableCopy绞佩、alloc創(chuàng)建出來是同一個(gè)單例寺鸥,內(nèi)存地址相同

  • 單例對(duì)象的釋放:在所有使用該單例的對(duì)象都釋放后,單例對(duì)象本身也會(huì)自己釋放 原文地址
+(instancetype)shareInstance {
    static __weak SingletonClass *instance;
    SingletonClass *strongInstance = instance;
    @synchronized(self) {
        if (strongInstance == nil) {
            strongInstance = [[[self class] alloc] init];
            instance = strongInstance;
        }
    }
    return strongInstance;
}

寫了個(gè)demo驗(yàn)證了品山,這樣創(chuàng)建的單例確實(shí)會(huì)隨著持有對(duì)象的銷毀而銷毀

2018-08-15 15:45:26.197552+0800 SingletonTest[65879:7837310] instanceAddress=0x600000000ef0,_content====the VC Hold Instance
2018-08-15 15:45:28.625037+0800 SingletonTest[65879:7837310] instanceAddress=0x600000000f10,_content====the Instance after VC dealloc Information

大概的思路是胆建,從A控制器進(jìn)入B控制器,B控制器創(chuàng)建一個(gè)單例肘交,打印此單例的信息笆载,然后B控制器回到A控制器,在A控制器創(chuàng)建單例并打印單例的信息涯呻,兩次打印的信息對(duì)比地址不同凉驻。

如果有錯(cuò)誤的地方,歡迎指正复罐。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末涝登,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子效诅,更是在濱河造成了極大的恐慌胀滚,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乱投,死亡現(xiàn)場(chǎng)離奇詭異咽笼,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)篡腌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門褐荷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嘹悼,你說我怎么就攤上這事叛甫〔愎” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵其监,是天一觀的道長(zhǎng)萌腿。 經(jīng)常有香客問我,道長(zhǎng)抖苦,這世上最難降的妖魔是什么毁菱? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮锌历,結(jié)果婚禮上贮庞,老公的妹妹穿的比我還像新娘。我一直安慰自己究西,他們只是感情好窗慎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著卤材,像睡著了一般遮斥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上扇丛,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天术吗,我揣著相機(jī)與錄音,去河邊找鬼帆精。 笑死较屿,一個(gè)胖子當(dāng)著我的面吹牛阔拳,可吹牛的內(nèi)容都是我干的高蜂。 我是一名探鬼主播怎顾,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼丛楚,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了固歪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎整吆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辉川,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡表蝙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了乓旗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片府蛇。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖屿愚,靈堂內(nèi)的尸體忽然破棺而出汇跨,到底是詐尸還是另有隱情务荆,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布穷遂,位于F島的核電站函匕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蚪黑。R本人自食惡果不足惜盅惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望忌穿。 院中可真熱鬧抒寂,春花似錦、人聲如沸掠剑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽澡腾。三九已至沸伏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間动分,已是汗流浹背毅糟。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留澜公,地道東北人姆另。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像坟乾,于是被迫代替她去往敵國(guó)和親迹辐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

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