ios单例的写法及理解

2017-06-27  本文已影响0人  zhaihongxia

1.ios的单例模式有两种官方写法:

1)不使用GCD的方式

#import  "Manager.h"

static   Manager   *manager;

@implementation  Manager

+(Manager *))shareManager {

         if (!manager) {

                   manager = [super  allocWithZone:NULL]  init];

          }

         return manager;

}

@end;

2)使用GCD的方式

#import  "Manager.h" 

@implementataion  Manager 

+(Manager *)shareManager {

             static  Manager *shareManager;

              static dispatch_once_t  predicate;

             dispatch_once(&predicate, ^{

                        shareManager =[super  allocWithZone:NULL]  init];

           });

          return   shareManager;

}

//注明:dispatch_once这个函数,他可以一次保证整个应用程序生命周期中某段代码只被执行

//不是使用alloc 方法,而是调用[super  allocWithZone:NULL]  init]; 已经重载allocWithZone基本的对象分配方法,所以要借用父类(NSObject)的功能来帮助处理底层内存分配的杂物

当我们调用shareManager方法时获取到的对象是相同的,但是但当我们通过alloc和init以及copy来构造对象依然会创建新的实例。确保对象的唯一,需要封锁用户通过alloc和init以及copy来构造这条道路。创建对象的步骤分为申请内存(alloc)、初始化(init),要确保对象的唯一性,在第一步这个阶段我们就要拦截它,当我们调用alloc方法时,oc内部会调用allocWithZone这个方法来申请内存,我们覆写这个方法,然后在这个方法调用shareManager返回单例对象。

+(id)allocWithZone:(struct _NSZone *)zone {

                 return     [Manager    shareManager];

}

-(id)copyWithZone:(NSZone *)zone {

           return    [Manager    shareManager];

}

-(id)mutablecopyWithZone:(NSZone *)zone {

           return    [Manager    shareManager];

}

@end

2.alloc和allocWithZone

在初始化一个对象时([Class alloc]  init];)其实做了两件事,alloc给对象分配内存空间,init是对对象的初始化,包括设置成员变量初始值这些工作。

而给对象分配内存空间,除了alloc方法之外还有另一个方法:allocWithZone.在NSObject类的官方文档里面,allocWithZone方法介绍说,该方法的参数是被忽略的,正确的做法是传nil或者NULL参数给他。(这个方法存在是历史遗留原因,文档里memory zone已经被弃用了,只是历史原因才保留这个接口)

实践证明,alloc方法初始化一个类的实例时,默认调用allocWithZone的方法,为了保持单例实例的唯一性需要覆盖所有会生成新的实例方法,如果有人初始化这个单例的时候不走allocWithZone,而是直接[Class  alloc]  init]; ,那么这个单例就不再是单例了,所以把这个方法堵上

3.NSZone?

上一篇下一篇

猜你喜欢

热点阅读