代码改变世界

【转】Objective-C在ARC下结合GCD的单例模式和宏模版

2013-04-02 16:32  maying_07  阅读(193)  评论(0编辑  收藏  举报

原文地址:http://blog.csdn.net/totogo2010/article/details/8373642

单例模式在iOS开发过程中经常用到,苹果提供过objective c单例的比较官方的写法:

 1 static MyGizmoClass *sharedGizmoManager = nil;
 2  
 3 + (MyGizmoClass*)sharedManager
 4 {
 5     @synchronized(self) {
 6         if (sharedGizmoManager == nil) {
 7             [[self alloc] init]; // assignment not done here
 8         }
 9     }
10     return sharedGizmoManager;
11 }
12  
13 + (id)allocWithZone:(NSZone *)zone
14 {
15     @synchronized(self) {
16         if (sharedGizmoManager == nil) {
17             sharedGizmoManager = [super allocWithZone:zone];
18             return sharedGizmoManager;  // assignment and return on first allocation
19         }
20     }
21     return nil; //on subsequent allocation attempts return nil
22 }
23  
24 - (id)copyWithZone:(NSZone *)zone
25 {
26     return self;
27 }
28  
29 - (id)retain
30 {
31     return self;
32 }
33  
34 - (unsigned)retainCount
35 {
36     return UINT_MAX;  //denotes an object that cannot be released
37 }
38  
39 - (void)release
40 {
41     //do nothing
42 }
43  
44 - (id)autorelease
45 {
46     return self;
47 }

现在iOS5之后普遍使用了ARC技术,原来这个写法就显得很累赘了,release已经不使用了。

 

咱们可以结合GCD来实现单例模式:

1 + (id)sharedInstance
2 {
3   static dispatch_once_t pred = 0;
4   __strong static id _sharedObject = nil;
5   dispatch_once(&pred, ^{
6     _sharedObject = [[self alloc] init]; // or some other init method
7   });
8   return _sharedObject;
9 }

使用dispatch_once,这个方法的意思是在应用程序生命周期内,这方法只执行一次,这就是ARC下结合GCD的一个单例的代码

 

因为我们可能需要多个单例的类,每个都写一次比较麻烦,可以更方便一些,把这些代码写成宏的形式,只需要传入类名就可以创建一个单例的类了。

通过传入类名创建头文件中单例方法的名称:

1 #define DEFINE_SINGLETON_FOR_HEADER(className) \
2 \
3 + (className *)shared##className;

通过传入类名创建单例方法的实现

 1 #define DEFINE_SINGLETON_FOR_CLASS(className) \
 2 \
 3 + (className *)shared##className { \
 4 static className *shared##className = nil; \
 5 static dispatch_once_t onceToken; \
 6 dispatch_once(&onceToken, ^{ \
 7 shared##className = [[self alloc] init]; \
 8 }); \
 9 return shared##className; \
10 }

使用宏:

 

在项目中新建了一个类testSingleton,并且有.h 和.m文件。

.h

.m中的代码:

1 #import "testSingleton.h"
2 
3 @implementation testSingleton
4 DEFINE_SINGLETON_FOR_CLASS(testSingleton)
5 @end
 1 #define DEFINE_SINGLETON_FOR_HEADER(className) \
 2 \
 3 + (className *)shared##className;
 4 
 5 #define DEFINE_SINGLETON_FOR_CLASS(className) \
 6 \
 7 + (className *)shared##className { \
 8 static className *shared##className = nil; \
 9 static dispatch_once_t onceToken; \
10 dispatch_once(&onceToken, ^{ \
11 shared##className = [[self alloc] init]; \
12 }); \
13 return shared##className; \
14 }
15 
16 #import <Foundation/Foundation.h>
17 
18 @interface testSingleton : NSObject
19 DEFINE_SINGLETON_FOR_HEADER(testSingleton);
20 @end

你可以把宏单独放到项目管理宏的文件中。这里是为了方便演示放到和testSingleton.h文件了。
获取单例:

1 - (void)test
2 {
3     testSingleton *testShare = [testSingleton sharedtestSingleton];
4 }