今天去面試,對(duì)方公司給的試卷中有一道題是寫(xiě)單例模式,面試的時(shí)候也問(wèn)了我單例模式的優(yōu)缺點(diǎn)。老實(shí)說(shuō)回答得相當(dāng)不好,對(duì)方也指出了我代碼中的不嚴(yán)謹(jǐn)?;貋?lái)自己從新查找了一下資料,重新總結(jié)了一下。
主要優(yōu)點(diǎn):
1、提供了對(duì)唯一實(shí)例的受控訪(fǎng)問(wèn)。
2、由于在系統(tǒng)內(nèi)存中只存在一個(gè)對(duì)象,因此可以節(jié)約系統(tǒng)資源,對(duì)于一些需要頻繁創(chuàng)建和銷(xiāo)毀的對(duì)象單例模式無(wú)疑可以提高系統(tǒng)的性能。
3、允許可變數(shù)目的實(shí)例。
主要缺點(diǎn):
1、由于單利模式中沒(méi)有抽象層,因此單例類(lèi)的擴(kuò)展有很大的困難。
2、單例類(lèi)的職責(zé)過(guò)重,在一定程度上違背了“單一職責(zé)原則”。
3、濫用單例將帶來(lái)一些負(fù)面問(wèn)題,如為了節(jié)省資源將數(shù)據(jù)庫(kù)連接池對(duì)象設(shè)計(jì)為的單例類(lèi),可能會(huì)導(dǎo)致共享連接池對(duì)象的程序過(guò)多而出現(xiàn)連接池溢出;如果實(shí)例化的對(duì)象長(zhǎng)時(shí)間不被利用,系統(tǒng)會(huì)認(rèn)為是垃圾而被回收,這將導(dǎo)致對(duì)象狀態(tài)的丟失.
以下是相對(duì)嚴(yán)謹(jǐn)?shù)淖龇?/p>
#import <Foundation/Foundation.h>
@interface Person : NSObject<NSCopying, NSMutableCopying>
+ (instancetype)sharePerson;
@end
#import "Person.h"
//全局
static Person *_person;
@implementation Person
//初始化方法
- (instancetype)init{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [super init];
});
return _person;
}
//單例方法
+ (instancetype)sharePerson{
return [[self alloc] init];
}
//alloc會(huì)調(diào)用allocWithZone,確保使用同一塊內(nèi)存地址
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_person = [super allocWithZone:zone];
});
return _person;
}
//copy的時(shí)候會(huì)調(diào)用copyWithZone
- (id)copyWithZone:(NSZone *)zone{
return _person;
}
+ (id)copyWithZone:(struct _NSZone *)zone{
return _person;
}
+ (id)mutableCopyWithZone:(struct _NSZone *)zone{
return _person;
}
- (id)mutableCopyWithZone:(NSZone *)zone{
return _person;
}
Person *person1 = [[Person alloc]init];
Person *person2 = [Person sharePerson];
Person *person3 = [[Person alloc]init];
Person *person4 = [person3 mutableCopy];
Person *person5 = [person4 copy];
NSLog(@"%p %p %p %p %p", person1, person2, person3, person4, person5);
// 0x170001ad0 0x170001ad0 0x170001ad0 0x170001ad0 0x170001ad0