我們經(jīng)常在編程中使用各種設(shè)計模式,在iOS中比較常見的設(shè)計模式有:單例模式、委托模式、觀察者模式智润,當(dāng)然實際上在Cocoa和Cocoa Touch框架中不僅僅是設(shè)計到這些設(shè)計模式,還有很多設(shè)計模式以及常規(guī)設(shè)計模式的變種等等永品。那什么是設(shè)計模式呢做鹰?
在軟件工程中,設(shè)計模式(design pattern)是對軟件設(shè)計中普遍存在(反復(fù)出現(xiàn))的各種問題鼎姐,所提出的解決方案。這個術(shù)語是由埃里细瘢·伽瑪(Erich Gamma)等人在1990年代從建筑設(shè)計領(lǐng)域引入到計算機科學(xué)的炕桨。(引自維基百科)
設(shè)計模式(Design pattern)是一套被反復(fù)使用、多數(shù)人知曉的肯腕、經(jīng)過分類編目的献宫、代碼設(shè)計經(jīng)驗的總結(jié)。使用設(shè)計模式是為了可重用代碼实撒、讓代碼更容易被他人理解姊途、保證代碼可靠性涉瘾。 毫無疑問,設(shè)計模式于己于他人于系統(tǒng)都是多贏的捷兰;設(shè)計模式使代碼編制真正工程化立叛;設(shè)計模式是軟件工程的基石脈絡(luò),如同大廈的結(jié)構(gòu)一樣贡茅。(引自百度百科)
通過解釋我們可以基本了解設(shè)計模式是什么這個問題秘蛇,當(dāng)然我們不在這里深入探討設(shè)計模式概念理論方面的問題,而是對我們在iOS開發(fā)中常用到的幾種設(shè)計模式進行梳理顶考,以方便日常開發(fā)赁还。
Tips:設(shè)計模式和架構(gòu)模式通常容易混淆
- 不同點 設(shè)計模式是解決某類常見問題的方法思路總結(jié)(尺度小) 框架模式是從軟件開發(fā)總體結(jié)構(gòu)上提出的一中框架結(jié)構(gòu)(尺度大)
- 共同點 降低耦合度驹沿、調(diào)高可拓展性艘策、易維護
比如:MVC是架構(gòu)模式,單例是設(shè)計模式
1. 單例模式(Singleton)
什么是單例
在程序的整個生命周期內(nèi),保證類只有一個實例對象并可在全局調(diào)用渊季。
如何實現(xiàn)單例
實現(xiàn)單例我們需要注意兩點:1.我們需要保證單例被實例化一次之后柬焕,不能被重復(fù)實例化2.在多線程模式下避免同時被一個以上的線程調(diào)用實例化方法而造成多個實例。
實現(xiàn)單例:
@synchronized同步鎖
static SingletonInstant *_single = nil;
@implementation SingletonInstant
+ (instancetype)sharedInstant {
if (!_single) { // 判斷放在加鎖之前防止多次加鎖
@synchronized(self) { // 添加同步鎖防止保證線程安全
_single = [[super allocWithZone:NULL] init];
}
}
return _single;
}
// 上面使用allocWithZone不使用alloc是因為alloc方法會調(diào)用
// allocWithZone方法梭域,如果使用alloc還要在重載的allocWithZone中
// 在實現(xiàn)一次判斷和加鎖斑举,因此為了簡化代碼,
// 直接使用allocWithZone病涨,在重載的方法中只要調(diào)用一次單例方法就可以了
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
return [self sharedInstant];
}
// copy方法也會調(diào)用copyWithZone方法富玷,因此直接返回self就好
- (id)copyWithZone:(NSZone *)zone {
return self;
}
@end
#pragma - mark MRC實現(xiàn)
static SingletonInstant *_single = nil;
+ (SingletonInstant*)sharedManager
{
if (_single == nil) {
@synchronized (self) {
_single = [[super allocWithZone:NULL] init];
}
}
return _single;
}
+ (id)allocWithZone:(NSZone *)zone
{
return [[self sharedManager] retain];
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
// 比ARC多出來的關(guān)于內(nèi)存管理的幾個方法
- (id)retain
{
return self;
}
- (NSUInteger)retainCount
{
return NSUIntegerMax; //denotes an object that cannot be released
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
更多關(guān)于alloc和allocWithZone的問題請查閱參考4
,MRC實現(xiàn)查閱參考3
GCD加鎖
使用 dispatch_once_t 保證線程安全
static SingletonInstant *_single = nil;
@implementation SingletonInstant
+ (instancetype)sharedInstant {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (!_single) {
_single = [[super allocWithZone:NULL] init];
}
});
return _single;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
return [self sharedInstant];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
@end
在dispatch_once方法中的代碼在程序的真?zhèn)€聲明周期只會執(zhí)行一次既穆。赎懦,關(guān)于GCD請自行學(xué)習(xí)。
MRC不再詳述
單例的實現(xiàn)基本雷同幻工,在網(wǎng)上也有一些大同小異的其他寫法励两,只要掌握單例思想,任何一種實現(xiàn)都是可以的囊颅,差異在細(xì)節(jié)上当悔,孰優(yōu)孰劣任君斟酌。