OC中的单例模式

来源:互联网 发布:php 查找字符串位置 编辑:程序博客网 时间:2024/05/21 07:53

单例模式在iOS开发中可能算是最常用的模式之一了.(废话不多说, 直接进入主题)

1. 什么是单例模式?

 a.整个程序运行期间, 永远只分配一块内存来创建对象

 b.最好提供一个类方法,返回内部唯一的一个对象(一个实例)


2. 该怎样去写?

2.1. 一般情况下, 我们可以这样写:

注意:当我们调用sharedInstance方法获取到的对象的确是相同的, 但是当我们通过allocinit来构造对象的时候, 得到的对象却不一样. 所以这样写是有缺陷的.

@interface Singleton : NSObject+ (instancetype)shareInstance ;@end @implementation Singleton static Singleton *_instance = nil; + (instancetype)sharedInstance{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _instance = [[self alloc] init];    }) ;         return _instance ;}


小结: 使用上面的这种方法, 导致我们通过不同的途径去创建得到不同的对象, 显然不行, 我们设计单例模式, 就必须要确保对象的唯一性, 所以我们就需要对alloc/init/copy等等方法进行过滤.
  创建对象时会进行alloc(申请内存)init(初始化)俩个步骤, 而调用alloc方法时, OC内部会调用allocWithZone来申请内存,  我们想要确保对象是唯一的, 所以我们得重写这些方法. 
ARC中: 需要重写 init方法, allocWithZone方法, copyWithZone方法:
static id _instance;- (id)init{    if (self = [super init]) {        // 加载资源        static dispatch_once_t onceToken;        dispatch_once(&onceToken, ^{                    });    }    return self;}+ (id)allocWithZone:(struct _NSZone *)zone{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _instance = [super allocWithZone:zone];    });    return _instance;}+ (instancetype)sharedInstance{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _instance = [[self alloc] init];    });    return _instance;}+ (id)copyWithZone:(struct _NSZone *)zone{    return _instance;}

而在MRC中, 因为需要手动释放内存, 但是如果真的释放了, 下次创建对象就会失败, 所以得多重写4个方法:
- (oneway void)release { } - (id)autorelease {     return _instance; } - (id)retain {     return _instance; } - (NSUInteger)retainCount {     return 1; } + (id)copyWithZone:(struct _NSZone *)zone {     return _instance; }

这样就可以了, 但是如果经常用到, 而且让我们不用关心ARC或MRC环境, 最好还是写个头文件, 将这些代码用一个宏来表示.
在这之前, 先了解以下 :
 a. 可以用宏来判断当前的环境(ARC or MRC)
#if __has_feature(objc_arc)#else//MRC#endif
b. 宏后面如果要表示多行, 则可以跟上 \ , 即表明有 \ 标记的都是属于这个宏的, 但是注意最后一行不能加上 \ .
c. 宏里面, 可以用## 来拼接参数

下面是头文件:(Singleton.h)
// ## : 连接字符串和参数#define singleton_h(name) + (instancetype)shared##name;#if __has_feature(objc_arc) // ARC#define singleton_m(name) \static id _instance; \+ (id)allocWithZone:(struct _NSZone *)zone \{ \    static dispatch_once_t onceToken; \    dispatch_once(&onceToken, ^{ \        _instance = [super allocWithZone:zone]; \    }); \    return _instance; \} \ \+ (instancetype)shared##name \{ \    static dispatch_once_t onceToken; \    dispatch_once(&onceToken, ^{ \        _instance = [[self alloc] init]; \    }); \    return _instance; \} \+ (id)copyWithZone:(struct _NSZone *)zone \{ \    return _instance; \}#else // 非ARC#define singleton_m(name) \static id _instance; \+ (id)allocWithZone:(struct _NSZone *)zone \{ \static dispatch_once_t onceToken; \dispatch_once(&onceToken, ^{ \_instance = [super allocWithZone:zone]; \}); \return _instance; \} \\+ (instancetype)shared##name \{ \static dispatch_once_t onceToken; \dispatch_once(&onceToken, ^{ \_instance = [[self alloc] init]; \}); \return _instance; \} \\- (oneway void)release \{ \\} \\- (id)autorelease \{ \return _instance; \} \\- (id)retain \{ \return _instance; \} \\- (NSUInteger)retainCount \{ \return 1; \} \\+ (id)copyWithZone:(struct _NSZone *)zone \{ \return _instance; \}

使用方法:
//.h类//引入这个宏文件#import "Singleton.h"@interface Object : NSObjectsingleton_h(name)@end//.m类@implementation Objectsingleton_m(name)@end





0 0
原创粉丝点击