在ios開發中,有很多地方都選擇使用單例模式。有很多時候必須要建立乙個物件,並且不能建立多個,用單例就為了防止建立多個物件。單例模式的意思就是某乙個類有且只有乙個例項。單例模式確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。這個類稱為單例類。
一、單例模式的三要點:
1. 該類有且只有乙個例項;
2. 該類必須能夠自行建立這個例項;
3. 該類必須能夠自行向整個系統提供這個例項。
二、單例模式的優點與缺點:
1. 記憶體占用與執行時間
對比使用單例模式和非單例模式的例子,在記憶體占用與執行時間存在以下差距:
(1) 單例模式:單例模式每次獲取例項時都會先進行判斷,看該例項是否存在——如果存在,則返回;否則,則建立例項。因此,會浪費一些判斷的時間。但是,如果一直沒有人使用這個例項的話,那麼就不會建立例項,節約了記憶體空間。
(2) 非單例模式:當類載入的時候就會建立類的例項,不管你是否使用它。然後當每次呼叫的時候就不需要判斷該例項是否存在了,節省了執行的時間。但是如果該例項沒有使用的話,就浪費了記憶體。
(3)例項控制:singleton 會阻止其他物件例項化其自己的 singleton 物件的副本,從而確保所有物件都訪問唯一例項。
靈活性:因為類控制了例項化過程,所以類可以更加靈活修改例項化過程。
2. 執行緒的安全性
(1) 從執行緒的安全性上來講,不加同步的單例模式是不安全的。比如,有兩個執行緒,乙個是執行緒a,另外乙個是執行緒b,如果它們同時呼叫某乙個方法,那就可能會導致併發問題。在這種情況下,會建立出兩個例項來,也就是單例的控制在併發情況下失效了。
(2) 非單例模式是執行緒安全的,因為程式保證只載入一次,在載入的時候不會發生併發情況。
(3) 單例模式如果要實現執行緒安全,只需要加上synchronized即可。但是這樣一來,就會減低整個程式的訪問速度,而且每次都要判斷,比較麻煩。
(4) 雙重檢查加鎖:為了解決(3)的繁瑣問題,可以使用「雙重檢查加鎖」的方式來實現,這樣,就可以既實現執行緒安全,又能使得程式效能不受太大的影響。
(4.1)
雙重檢查加鎖機制——並不是每次進入要呼叫的方法都需要同步,而是先不同步,等進入了方法之後,先檢查例項是否存在,如果不存在才進入下面的同步塊,這是
第一重檢查。當進入同步塊後,再次檢查例項是否存在,如果不存在,就在同步的情況下建立乙個例項,這是第二重檢查。這樣一來,就只需要同步一次,從而減少
了多次在同步情況下進行判斷所浪費的時間。
(4.2)
雙重檢查加鎖機制的實現,會使用乙個關鍵字volatile。它的意思是:被volatile修飾的變數的值,將不會被本地執行緒快取,所有對該變數的讀寫
都是直接操作共享記憶體的,從而確保了多個執行緒能正確的處理該變數。這種實現方式既可以實現執行緒安全地建立例項,而又不會對效能造成太大的影響。它只是在第
一次建立例項的時候同步,以後就不需要同步了,從而加快了執行速度。
3. 單例模式會阻止其它物件例項化其自己的物件的副本,從而確保所有物件都訪問唯一例項。
4. 因為單例模式的類控制了例項化的過程,所以類可以更加靈活修改例項化過程。
三、ios中的單例模式
1. 基本步驟:
(1) 為單例物件建立乙個靜態例項,可以寫成全域性的,也可以在類方法裡面實現,並初始化為nil;
(2) 實現乙個例項構造方法,檢查上面宣告的靜態例項是否為nil,如果是,則建立並返回乙個本類的例項;
(3) 重寫allocwithzone方法,用來保證其他人直接使用alloc和init試圖獲得乙個新實力的時候不產生乙個新例項;
(4) 適當實現allocwithezone,copywithzone,release和autorelease。
//第一步:靜態例項,並初始化。
static surveyruntimedata *sharedobj = nil;
@implementation surveyruntimedata
//第二步:例項構造檢查靜態例項是否為nil
}return sharedobj;
}//第三步:重寫allocwithzone方法
+ (id) allocwithzone:(nszone *)zone
}return nil;
}//第四步
- (id) copywithzone:(nszone *)zone
//一下方法再xcode5以上,已經不需要!大家根據事情情況自行判斷!
- (id) retain
- (unsigned) retaincount
- (oneway void) release
- (id) autorelease
- (id)init
}@end
+(id)allocwithzone:(nszone *)zone
}return nil;
}nszone: 簡單來說可以把它想象成乙個記憶體池,alloc或者dealloc這些操作都是在這個記憶體池中操作的,cocoa總是會分配乙個預設的nszone,任何 預設記憶體操作都是在這個zone上進行的,使用預設zone存在缺陷,因為他是全域性範圍的,頻繁使用會導致記憶體的碎片化,尤其是大量的alloc和 dealloc的時候,效能上會受到一定影響。因為你完全可以自己生成乙個zone並將alloc,copy這些限制在這個zone中。
iOS開發之單例模式
單例模式是一種常用的軟體設計模式,在應用這個模式時,單例物件的類必須保證只有乙個例項存在。通過單例模式可以保證系統中乙個類只有乙個例項而且該例項易於外界訪問,從而方便對例項個數的控制並節約系統資源。如果希望在系統中某個類的物件只能存在乙個,單例模式是最好的解決方案。單例的實現步驟 1 重寫alloc...
iOS 開發之單例模式
單例就是工程中只初始化一次,節省記憶體空間,或者共享資源。例如在建立藍芽類,或者做wifi通訊時經常用到。也可以用來傳值。一下介紹兩種建立單例的方法 一,考慮執行緒安全的寫法 考慮執行緒安全的寫法 return modeltool物件 instancetype sharemodel return m...
iOS開發之單例模式
什麼是單例 單例模式是一種常用的軟體設計模式。在它的核心結構中只包含乙個被稱為單例類的特殊類。通過單例模式可以保證系統中乙個類只有乙個例項而且該例項易於外界訪問,從而方便對例項個數的控制並節約系統資源。如果希望在系統中某個類的物件只能存在乙個,單例模式是最好的解決方案。ios開發中如何使用單例?傳統...