iOS 单例

制造单例对象的步骤,例如做1个httpTool的单例

1. 必须有一个全局实例

static HttpTool *_instance;

2.提供生成单例对象的类方法

+ (id)sharedHttpTool

{  

  if(_instance == nil){

   _instance = [[self alloc] init];

  }

  return _instance;

}

3.如果有人使用  [ [ httpTool alloc ] init ] 去生成实例,依然会生成新的实例,所以需要拦截alloc-init方法,alloc-init方法内部会调用allocWithZone方法,重写此方法即可实现拦截

+ (id)allocWithZone:(NSZone *)zone

{
  // 敲dispatch_once有智能提醒

  static dispatch_once_t onceToken;

  dispatch_once(&onceToken,^{

    _instance = [super allocWithZone:zone];  

  });

  return _instance;

}

至此ARC项目中单例就做好了.

4. 如果是MRC项目

4.1 为了防止其他人把单例对象释放调,必须拦截release方法

- (oneway void)release {  // 啥也不写,让该方法空执行  }

4.2 单例对象的retain count始终为1,因此还需要重写retain方法

- (id)retain {  return self;    }

- (NSUInteger)retainCount {  return 1;  }

- (id)autorelease {  return self;  }

4.3 再严谨一点,把copy也重写了.让copy时,也始终返回一个实例

+ (id) copyWithZone:(NSZone *)zone { return _instance;   }

至此httpTool的单例对象就真的做完了,如果account类也要做成单例,步骤如下:

 

5. 但是单例使用太频繁了,如果account类也要做成单例,又要重复以上步骤

.h文件

+ (id)sharedAccount;

.m文件

static Account *_instance;

+ (id)sharedAccount{  //……  }

+ (id)allocWithZone:(NSZone *)zone { //……  }

通过上面的代码可以知道,无非就是把类名替换一下而已,所以为了快速生成单例,使用宏.

利用宏来快速生成单例

.h文件

#define  single_interface(class)  +(class *)shared##class

.m文件  ps: 每一行末尾加\是告诉编译器 下面那行也是宏的一部分,最后一行不要加\

#define single_implementation(class) \

static class *_instance; \

+ (id)shared##class{ \ 

  if(_instance == nil){ \

   _instance = [[self alloc] init]; \

  } \

  return _instance; \

} \

+ (id)allocWithZone:(NSZone *)zone{ \

  static dispatch_once_t onceToken; \

  dispatch_once(&onceToken,^{ \

    _instance = [super allocWithZone:zone]; \ 

  }); \

  return _instance; \

}

 为了便于拷贝,提供一下代码:

 1 //把本段代码放在pch文件里
 2 #define  single_interface(class)  + (class *)shared##class;
 3 
 4 
 5 #define single_implementation(class) \
 6 static class *_instance; \
 7 \
 8 + (class *)shared##class \
 9 { \
10 if (_instance == nil) { \
11 _instance = [[self alloc] init]; \
12 } \
13 return _instance; \
14 } \
15 \
16 + (id)allocWithZone:(NSZone *)zone \
17 { \
18 static dispatch_once_t onceToken; \
19 dispatch_once(&onceToken, ^{ \
20 _instance = [super allocWithZone:zone]; \
21 }); \
22 return _instance; \
23 }
1 // 欲做成单例的类的.h文件,例如httpTool类
2 #import <Foundation/Foundation.h>
3 @class QKinstance;
4 @interface QKinstance : NSObject
5 single_interface(QKinstance)
6 @end
1 // 欲做成单例的类的.m文件
2 #import "QKinstance.h"
3 @implementation QKinstance
4 single_implementation(QKinstance)
5 @end

 

posted @ 2015-01-14 14:40  oumygade  阅读(160)  评论(0编辑  收藏  举报