標籤:使用 os io ar art 問題 cti div
單例模式是iOS常用設計模式中的一種。單例設計模式的作用是使得這個類的一個對象成為系統中的唯一執行個體,因此需要用一種唯一的方法去建立這個對象並返回這個對象的地址。那麼,我們何時使用單例模式呢?1、類只能有一個執行個體,而且必須從一個為人熟知的訪問點對其訪問。2、這個唯一的執行個體只能通過子類化進行擴充,而且擴充的對象不會破壞用戶端代碼。
那麼用Objective-C如何?單例模式呢?下面我們來建立一個Singleton類,在Singleton.h中實現如下
- @interface Singleton : NSObject
-
- + (Singleton *) sharedInstance;
-
- @end
在Singleton.m
- @implementation Singleton
-
- static Singleton * sharedSingleton = nil;
-
- + (Singleton *) sharedInstance
- {
- if (sharedSingleton == nil) {
- sharedSingleton = [[Singleton alloc] init];
- }
- return sharedSingleton;
- }
-
- @end
這樣就建立一個簡單的單例模式,實際上有一部分程式員也是這樣實現的,但實際上這是一個不“嚴格”版本,在實際中使用,可能會遇到發起調用的對象不能以其他分配方式執行個體化單例對象,否則,就會建立多個執行個體。(之前有人和我討論過這個問題,說使用者應該嚴格按照介面來使用,當實際上Singleton是一個對象,我們不能保證使用者不會使用其他的方法去建立(比如alloc),這個時候他就會建立多個執行個體,這樣就會出現這些無法感知的bug)
下面我對Singleton.m的進行改進
- @implementation Singleton
-
- static Singleton * sharedSingleton = nil;
-
- + (Singleton *) sharedInstance
- {
- if (sharedSingleton == nil) {
- sharedSingleton = [[super allocWithZone:NULL] init];
- }
- return sharedSingleton;
- }
-
- + (id) allocWithZone:(struct _NSZone *)zone
- {
- return [[self sharedInstance] retain];
- }
-
- - (id) copyWithZone:(NSZone *) zone
- {
- return self;
- }
-
- - (id) retain
- {
- return self;
- }
-
- - (NSUInteger) retainCount
- {
- return NSUIntegerMax;
- }
-
-
- - (void) release
- {
- //
- }
-
- - (id) autorelease
- {
- return self;
- }
-
- @end
也許你注意到了,我重載了allocWithZone:,保持了從sharedInstance方法返回的單例對象,使用者哪怕使用alloc時也會返回唯一的執行個體(alloc方法中會先調用allocWithZone:建立對象)。而retain等記憶體管理的函數也被重載了,這樣做讓我們有了把Singleton類變得“嚴格”了。