Objective-C的單例模式如何新建和測試?



所謂單例模式是一種最簡單的設計模式之一,就是程序中一個類只對應着一個實例,在很多編程語言中都有這種模式,比如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的創建及使用


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章