iOS单例解析

2 篇文章 0 订阅

看到一个对于单例的很好地描述. 从内存上对单例模式进行了详细的介绍, get新技能.原网址:http://blog.sina.com.cn/s/blog_71715bf80101a8mm.html


IOS单例模式(Singleton)

单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。

1.单例模式的要点:

  显然单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。

2.单例模式的优点:

  1.实例控制:Singleton 会阻止其他对象实例化其自己的 Singleton 对象的副本,从而确保所有对象都访问唯一实例。
  2.灵活性:因为类控制了实例化过程,所以类可以更加灵活修改实例化过程
 
IOS中的单例模式
  在objective-c中要实现一个单例类,至少需要做以下四个步骤:
  1、为单例对象实现一个静态实例,并初始化,然后设置成nil,
  2、实现一个实例构造方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,
  3、重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例,
  4、适当实现allocWitheZone,copyWithZone,release和autorelease。

 

按照一般的思路,如下

static MyClass *class = nil;

@implementation MyClass

+(MyClass *)sharedMyClass{

@synchronized (self){

     if (!class) {

          [[self allocinit];//非ARC模式下

    }

}

    return class;

}

@end

 

调试发现

MyClass *A = [[MyClass allocinit];

NSLog(@"A:%@",A);

MyClass *B = [MyClass sharedMyClass];

NSLog(@"B:%@",B);

 

打印出的是

 

A:<MyClass: 0x6c72d30>

B:<MyClass: 0x6a87e60>

不是一个内存地址,也就是不是同一个实体

 

官方如下方式实现

 

static MyClass *class = nil;


@implementation MyClass


+(MyClass *)sharedMyClass{

    @synchronized (self){//为了确保多线程情况下,仍然确保实体的唯一性

        

        if (!class) {

            

            [[self alloc] init];//ARC模式下,该方法会调用 allocWithZone

            

        }

        return class;

    }

}




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

    @synchronized(self){

        

        if (!class) {

            

            class = [super allocWithZone:zone]; //确保使用同一块内存地址

            

            return class;

            

        }

        

        return nil;

    }

}


- (id)init;

{

    @synchronized(self) {

        

        if (self = [super init]){

            

            return self;

        }

        

        return nil;

    }

}


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

    

    return self; //确保copy对象也是唯一

    

}




-(id)retain{

    

    return self; //确保计数唯一

    

}




- (unsigned)retainCount


{

    

    return UINT_MAX //装逼用的,这样打印出来的计数永远为-1

    

}




- (id)autorelease


{

    

    return self;//确保计数唯一

    




- (oneway void)release


{

    

    //重写计数释放方法

    

}

 

再调试

MyClass *A = [[MyClassallocinit];

NSLog(@"A:%@",A);

MyClass *B = [MyClasssharedMyClass];

NSLog(@"B:%@",B);

MyClass *C = [A copy];

NSLog(@"C:%@",C);

 

打印出的是

 

A:<MyClass: 0x6a1e130>

B:<MyClass: 0x6a1e130>

C:<MyClass: 0x6a1e130>

都是指向同一块内存地址

答案已经出来了

apple建议的方式显然真正的确保了实体的唯一性


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值