iOS 单例


iOS 单例



单例的应用十分普遍,单例模式使一个类只有一个实例。

优点:易于供外界访问,方便控制实例个数,节约系统资源。


一、ARC中实现单例

1,定义一个全局的静态变量 _instance,用来记录“第一次”被实例化出来的对象;

2,重写 allocWithZone 方法,此方法是为对象分配内存空间而必须调用的一个方法

因此,在此方法中使用“dispatch_once”,能够保证在多线程中 _instance也只会被“分配”一次空间;

3,定义一个 shareDataManager “类”方法,方便其他使用单例的对象调用此单例,在此方法中同样使用“dispatch_once”;

注:如果不考虑copy&MRC,以上三个步骤即可!

4,如果需要支持copy,则需要:

(1),遵守NSCopying协议;

(2),在copyWithZone方法中,直接返回_instance;


为什么要使用dispatch_once?

原因:防止多线程同时进来,相当于与Java单例中的加锁机制,保证只被实例化一次。但这里使用的不是synchronized(同步),是类似互斥锁的东西,但比他的性能更高。


ARC中实现单例的代码:


#pragma mark -单例

/**

 步骤:

 1.一个静态变量_inastance

 2.重写allocWithZone,在里面用dispatch_once, 并调用super allocWithZone

 3.自定义一个sharedXX,用来获取单例. 在里面也调用dispatch_once,实例化_instance

 -----------可选------------

 4.如果要支持copy.(先遵守NSCopying协议)重写copyWithZone,直接返回_instance即可.

 */


/**1:存储唯一实例*/

static OrderDataManager *_instance =nil;





/**

 *  2:分配内存孔家时都会调用这个方法. 保证分配内存alloc时都相同

 *

 *  @param zone zone

 *

 *  @return _instance

 */

+(id)allocWithZone:(struct_NSZone *)zone

{

    //调用dispatch_once保证在多线程中也只被实例化一次

    staticdispatch_once_t onceToken;


    dispatch_once(&onceToken, ^{

        _instance = [superallocWithZone:zone];

    });

    

    return_instance;

}




/**

 *  3:保证init初始化时都相同

 *

 *  @return _instance

 */

+(instancetype)sharedManager

{

    staticdispatch_once_t onceToken;


    //调用dispatch_once保证在多线程中也只被实例化一次

    dispatch_once(&onceToken, ^{

        _instance = [[OrderDataManageralloc] init];

    });

    

    return_instance;

}



/**

 *  4:保证copy时都相同

 *

 *  @param zone zone

 *

 *  @return _instance

 */

-(id)copyWithZone:(NSZone *)zone

{

    return_instance;

}







二、MRC中实现单例

因为单例对象是用static标记过的,因此存放在静态区,在MRC中不需要我们去管理,但还需要覆盖一些内存管理方法。

实现部分与ARC一致,MRC覆盖的内存管理方法如下:



#pragma mark - MRC中需要覆盖的方法


/**

 *  不需要计数器+1

 *

 *  @return self

 */

- (id)retain

{

    returnself;

}



/**

 *  不需要.堆区的对象才需要

 *

 *  @return self

 */

- (id)autorelease

{

    returnself;

}


/**

 *  不需要

 *

 *  @return void

 */

- (onewayvoid)release

{

}





/**

 *  不需要计数器个数.直接返回最大无符号整数

 *

 *  @return UINT_MAX

 */

- (NSUInteger)retainCount

{

    //参照常量区字符串的retainCount

    returnUINT_MAX;

}







三、ARC与MRC的整合

整合是为了方便单例既能在ARC中使用,又能在MRC中使用,而不必去修改单例中的方法。

具体做法是使用宏定义,判断是否是ARC环境,代码如下:


#if !__has_feature(objc_arc)

//MRC中内存管理的方法放在这个地方

#endif





参考文章:

http://blog.csdn.net/xn4545945  

http://blog.csdn.net/xn4545945/article/details/37586519


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值