Singleton 可以把它想成是一個全域物件,就如同全域變數一般,在整個程式中只會有單一一個這樣的物件,這類的技巧很常在撰寫遊戲程式時被使用,除了可以減少記憶體資源的過度浪費外,也可以減少許多參數在傳遞上的困擾,下列程式碼就示範如何製作出一個 Singleton 物件,與它的使用方式。
在製作出 Singleton 物件方面,我們賦予這個物件一個 count 值,並提供兩個實體方法,用來疊加和呈現這個 count 值。新增一個 NSObject 的 Subclass 並命名為 SingletonObject,以下是此物件內部的完整程式碼。
SingletonObject.h
#import <Foundation/Foundation.h>
@interface SingletonObject : NSObject {
@private
int count;
}
//統一透過此函式來調用SingletonObject的方法
+ (SingletonObject *)sharedSingletonObject;
//疊加
- (void)addCount;
//呈現
- (void)showCount;
@end
SingletonObject.m
#import "SingletonObject.h"
@implementation SingletonObject
//宣告一個靜態的SingletonObject物件
static SingletonObject *_singletonObject = nil;
- (id)init {
self = [super init];
if (self) {
//將COUNT初始化為0
count = 0;
}
return self;
}
//執行時會判斷是否_singletonObject已經完成記憶體配置
+ (SingletonObject *)sharedSingletonObject {
@synchronized([SingletonObject class]) {
//判斷_singletonObject是否完成記憶體配置
if (!_singletonObject)
[[self alloc] init];
return _singletonObject;
}
return nil;
}
+ (id)alloc {
@synchronized([SingletonObject class]) {
//避免 [SingletonObject alloc] 方法被濫用
NSAssert(_singletonObject == nil, @"_singletonObject 已經做過記憶體配置");
_singletonObject = [super alloc];
return _singletonObject;
}
return nil;
}
- (void)addCount {
count += 1;
}
- (void)showCount {
NSLog(@"%d", count);
}
- (void)dealloc {
[super dealloc];
}
@end
在上述程式碼中有使用到 NSAssert 指令,它可以用來避免 [SingletonObject alloc] 方法遭到濫用,因而製作出第二個 SingletonObject 的 instance,這就違背了當初我們建立 SingletonObject 的初衷。
此物件在使用上也非常簡單,只要使用下列程式碼便可以操作 SingletonObject 中的方法。
[[SingletonObject sharedSingletonObject] addCount];
[[SingletonObject sharedSingletonObject] showCount];
至於要如何證明 SingletonObject 在程式中只存在單一一個呢?首先,我們建立一個新的物件並在它程式初始化的地方將 count 值疊加三次,程式瑪如下。
OtherObject.m
#import "OtherObject.h"
#import "SingletonObject.h"
@implementation OtherObject
- (id)init {
self = [super init];
if (self) {
[[SingletonObject sharedSingletonObject] addCount];
[[SingletonObject sharedSingletonObject] addCount];
[[SingletonObject sharedSingletonObject] addCount];
}
return self;
}
- (void)dealloc {
[super dealloc];
}
@end
接著,回到主要程式碼比較一下在宣告此物件之前與之後的 count 值,如果兩個數值一樣,那麼表示在宣告 OtherObject 時所曡加的其實是另一個 SingletonObject 的 instance,若是兩者的數值差距為 3,則表示我們已經成功製作出一個 Singleton 單一(全域)物件,其程式瑪如下。
#import <Foundation/Foundation.h>
#import "SingletonObject.h"
#import "OtherObject.h"
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
[[SingletonObject sharedSingletonObject] showCount];
//宣告一個OtherObject物件
OtherObject *theObject = [[OtherObject alloc]init];
[theObject release];
[[SingletonObject sharedSingletonObject] showCount];
[pool drain];
return 0;
}
請問Singleton 這個Object該如何去release呢?
回覆刪除謝謝
null 就可以了
刪除