很多人面試都有被問(wèn)到單例,單例并不陌生,但是要想說(shuō)的完整,可以參考我整理的以下資料,希望能幫到大家
手寫單例(從實(shí)現(xiàn)單例的幾種方式, 單例在內(nèi)存中的位置, 單例的生命周期等等方面作答)
(是什么)單例模式的意思就是只有一個(gè)實(shí)例尽超。(作用)單例模式確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例,節(jié)約系統(tǒng)資源梧躺。(使用場(chǎng)合) 在整個(gè)應(yīng)用程序中,共享一份資源(這份資源只需要?jiǎng)?chuàng)建初始化一次). 例如
一些網(wǎng)絡(luò)工具類/沙盒工具類/打印機(jī)/視圖窗口/等等
(單例模式的種類)分為懶漢式(用到的時(shí)候在加載)似谁、惡漢式(程序已啟動(dòng)就加載)-==>>調(diào)用load方法,在程序已進(jìn)入就有
(單例模式實(shí)現(xiàn)的方法)互斥鎖(同步鎖) dispatch_once
(單例在內(nèi)存中的位置) static修飾的, 存在常量區(qū)
(單例的生命周期)跟隨著AppDelegate的銷毀而銷毀
單例需要重寫的方法:
模仿蘋果源生的寫法創(chuàng)建單例單例的方法名都是share+xxxx的一個(gè)形式,這也是大家在使用單例時(shí)默認(rèn)的方法但是為了防止單例被用alloc init的方法創(chuàng)建出來(lái)需要重寫
+ (instancetype)allocWithZone:(struct _NSZone *)zone(該方法在調(diào)用alloc init方法時(shí)會(huì)自定調(diào)用掠哥,保證單例只開(kāi)辟一個(gè)空間)
+(instancetype)copyWithZone:(struct _NSZone *)zone(同時(shí)為了防止使用copy創(chuàng)建單例需要重寫,遵守<NSCoping>協(xié)議)
+(instancetype)share+xxxx;(最后提供一個(gè)外界方法創(chuàng)建唯一的實(shí)例 )
static id instance;//指的是Singleton這個(gè)類,把對(duì)象定義為靜態(tài)的全局變量,始終指向?qū)嵗龅膶?duì)象
+ (instancetype)sharedSingleton{
//GCD寫法 (執(zhí)行效率高)
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ singleton = [[Singleton alloc]init]; });
return instance;
}
MRC 中增加如下方法的實(shí)現(xiàn):
- (instancetype)retain { return self; } 因?yàn)橹挥幸粋€(gè)實(shí)例對(duì)象巩踏,所以retain不能增加引用計(jì)數(shù)。
- (NSUInteger)retainCount { return 1; } 因?yàn)橹挥幸粋€(gè)實(shí)例對(duì)象续搀,設(shè)置默認(rèn)引用計(jì)數(shù)塞琼。這里是可以取的NSUInteger的最大值,當(dāng)然也可以設(shè)置成1或其他值禁舷。
- (oneway void)release { } oneway void是用于多線程編程中彪杉,表示單向執(zhí)行,不能“回滾”牵咙,即原子操作
- (instancetype)autorelease { return self; }
<p>
代碼如下
#import "Singleton.h"
@interface Singleton()<NSCopying>
@end
@implementation Singleton
//全局的變量,指的就是Singleton這個(gè)對(duì)象,靜態(tài)全局變量派近,始終指向?qū)嵗龅膶?duì)象
static id instance;
//
+ (instancetype)shardSingleton{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
//創(chuàng)建類
instance = [[self alloc]init];
});
return instance;
}
//創(chuàng)建alloc init 時(shí)候創(chuàng)建,會(huì)調(diào)用allocWithZone ,保證創(chuàng)建出來(lái)這個(gè)對(duì)象是唯一的
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
//返回自己
instance = [super allocWithZone:zone];
});
return instance;
}
//防止外界拷貝造成多個(gè)實(shí)例
- (id)copyWithZone:(NSZone *)zone{
return instance;
}
//若果是MRC,不僅要實(shí)現(xiàn)以上的copyWithZone,allocWithZone
//需要實(shí)現(xiàn)release,autorelease,retain,retainCount
/**
oneway void是用于多線程編程中,表示單向執(zhí)行洁桌,不能“回滾”渴丸,即原子操作
- (oneway void)release{
//單例模式不需要被釋放
}
- (instacetype)autorelease{
return instace;//
}
因?yàn)橹挥幸粋€(gè)實(shí)例對(duì)象,所以retain不能增加引用計(jì)數(shù)
- (instacetype)retain{
return instance;
}
- (NSUInteger)retainCount{
return 1;
}
*/