所謂單例模式是一種最簡單的設計模式之一,就是程序中一個類只對應着一個實例,在很多編程語言中都有這種模式,比如objective-c編程語言、Java語言。對於objective-c來說,其單例模式是怎樣的呢?如何表現呢?今天小編圍繞這個問題,整理了一篇相關文章,分享給大家,一起來get新技能吧。
單例模式一般用全局靜態對象來實現。下面我們通過建立一個生成單例的類SingletonClass,在實現文件中定義各種方法來實現我們的單例模式。
1、單例模式一般用全局靜態對象來實現,所以我們在SingletonClass.m中定義一個靜態全局變量是少不了的:
//定義靜態全局變量
staticSingletonClass *single = nil;
//定義靜態全局變量
staticSingletonClass *single = nil;
2、上面的靜態變量是定義在實現文件中的,所以是私有的,要想獲取該類的實例得有個getInstance方法來獲取實例,在給靜態變量分配內存空間之前,首先要判斷是否已經分配過啦,確保單例,如果分配過了就不分配了。
//獲取靜態全局對象
+(id)getInstance
{
//如果沒有生成對象,則爲靜態全局變量分配內存
if (single == nil) {
single = [[SingletonClass alloc] init];
}
return single;
}
//獲取靜態全局對象
+(id)getInstance
{
//如果沒有生成對象,則爲靜態全局變量分配內存
if (single == nil) {
single = [[SingletonClass alloc]init];
}
return single;
}
3、爲了防止用戶通過alloc和new來實例化對象,因此我們要對類方法allcoWithZone進行重寫
//防止通過alloc或者new來創建新的對象我們要重寫allocWithZone
+(id)allocWithZone:(NSZone*)zone
{
if (single == nil) {
single = [[super allocWithZone:zone]init];
}
return single;
}
//防止通過alloc或者new來創建新的對象我們要重寫allocWithZone
+(id)allocWithZone:(NSZone*)zone
{
if (single == nil) {
single =[[superallocWithZone:zone]init];
}
return single;
}
4、爲了防止用戶把單例進行深淺拷貝,我們需要重寫copyWithZone方法和mutableCopyWithZone方法,在重寫方法之前我們的單例類必須遵循協議NSCoping和NSMutableCoping協議
遵循協議代碼如下:
@interfaceSingletonClass : NSObject
//單例中獲取單例對象的方法
+(id)getInstance;
//單例測試方法
-(void)singletonFunction;
@end
@interfaceSingletonClass:NSObject
//單例中獲取單例對象的方法
+(id)getInstance;
//單例測試方法
-(void)singletonFunction;
@end
重寫copyWithZone方法
//爲了防止通過copy來創建新的實例我們要重寫copyWithZone;
-(id)copyWithZone:(NSZone*)zone
{
return self;
}
//爲了防止通過copy來創建新的實例我們要重寫copyWithZone;
-(id)copyWithZone:(NSZone*)zone
{
return self;
}
重寫mutableCopyWithZone方法
-(id)mutableCopyWithZone:(NSZone*)zone
{
return self;
}
-(id)mutableCopyWithZone:(NSZone*)zone
{
return self;
}
5、防止用戶把創建的單例dealloc,我們需要重寫retainCount方法
//重寫retainCount方法,防止被dealloc,返回最大值
-(NSUInteger)retainCount
{
return NSUIntegerMax;
}
//重寫retainCount方法,防止被dealloc,返回最大值
-(NSUInteger)retainCount
{
return NSUIntegerMax;
}
6、重寫release,autorelease, retain方法
//重寫retain,引用計數不變
-(id) retain
{
return self;
}
//重寫release
-(oneway void)release
{
}
//重寫autorelease
-(id)autorelease
{
return self;
}
//重寫retain,引用計數不變
-(id) retain
{
return self;
}
//重寫release
-(oneway void)release
{
}
//重寫autorelease
-(id)autorelease
{
return self;
}
至此我們的單例模式基本創建完畢,下面開始我們的測試吧;
在main函數中的代碼如下:
//單例模式的測試
SingletonClass*single1 = [SingletonClass getInstance];
SingletonClass*single2 = [SingletonClass new];
SingletonClass*single3 = [[SingletonClass alloc] init];
SingletonClass*single4 = [single1 copy];
SingletonClass*single5 = [single1 mutableCopy];
SingletonClass*single6 = [single1 retain];
[single1release];
[single1singletonFunction];
NSLog(@"single_retainCount= %lu", single1.retainCount);
//輸出地址
NSLog(@"getInstance single1_P = %p", single1);
NSLog(@"new single2_P = %p", single2);
NSLog(@"allo single3_P = %p", single3);
NSLog(@"copy single4_P = %p", single4);
NSLog(@"mutableCopy single5_P = %p", single5);
NSLog(@"retain single6_P = %p", single6);
//單例模式的測試
SingletonClass*single1 = [SingletonClass getInstance];
SingletonClass*single2 = [SingletonClass new];
SingletonClass*single3 = [[SingletonClass alloc]init];
SingletonClass*single4 = [single1copy];
SingletonClass*single5 = [single1mutableCopy];
SingletonClass*single6 = [single1retain];
[single1release];
[single1singletonFunction];
NSLog(@"single_retainCount= %lu", single1.retainCount);
//輸出地址
NSLog(@"getInstance single1_P = %p", single1);
NSLog(@"new single2_P = %p", single2);
NSLog(@"allo single3_P = %p", single3);
NSLog(@"copy single4_P = %p", single4);
NSLog(@"mutableCopy single5_P = %p", single5);
NSLog(@"retain single6_P = %p", single6);
運行結果如下:
2014-08-0716:04:44.207 Memory[20664:303] singleton Ps: 我是單例模式中得測試方法!!
2014-08-0716:04:44.207 Memory[20664:303] single_retainCount = 18446744073709551615
2014-08-0716:04:44.207 Memory[20664:303] getInstance single1_P = 0x100204690
2014-08-0716:04:44.208 Memory[20664:303] new single2_P = 0x100204690
2014-08-0716:04:44.208 Memory[20664:303] alloC single3_P = 0x100204690
2014-08-0716:04:44.208 Memory[20664:303] copy single4_P = 0x100204690
2014-08-0716:04:44.209 Memory[20664:303] mutableCopy single5_P = 0x100204690
2014-08-0716:04:44.209 Memory[20664:303] retain single6_P = 0x100204690
2014-08-0716:04:44.207 Memory[20664:303]singleton Ps: 我是單例模式中得測試方法!!
2014-08-0716:04:44.207 Memory[20664:303]single_retainCount = 18446744073709551615
2014-08-0716:04:44.207 Memory[20664:303]getInstance single1_P = 0x100204690
2014-08-0716:04:44.208 Memory[20664:303] new single2_P = 0x100204690
2014-08-0716:04:44.208 Memory[20664:303]alloC single3_P = 0x100204690
2014-08-0716:04:44.208 Memory[20664:303]copy single4_P = 0x100204690
2014-08-0716:04:44.209 Memory[20664:303]mutableCopy single5_P = 0x100204690
2014-08-0716:04:44.209 Memory[20664:303]retain single6_P = 0x100204690
單例的地址是不變的。
上面是在非ARC模式下得單例模式,那麼在ARC模式下我們應如何實現我們的單例模式呢,我們下面就會給出ARC下的單例模式,用下面的方法,因沒有重寫alloc,copy等方法,通過alloc還是可以給該對象分配一個新對象的,上面是線程不安全的,下面是線程安全的:
+(id)sharedSingleton {
static MySingleton *sharedSingleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedSingleton = [[self alloc] init];
});
return sharedSingleton;
}
+ (id)sharedSingleton {
static MySingleton *sharedSingleton = nil;
static dispatch_once_tonceToken;
dispatch_once(&onceToken, ^{
sharedSingleton = [[self alloc] init];
});
return sharedSingleton;
}
以上就是objective-c編程語言中,單例模式的建立及實現方法,有興趣的童鞋可以嘗試自己實現一下。
相關文章:《Objective-C中NSMutableArray的創建及使用》