IOS 单例模式

单例模式几乎是所有设计模式中最简单的形式之一,使用单例模式时,要求单例对象的类必须保证只有一个实例存在,并提供一个访问它的全局访问点。也就是说,一个类只创建一个实例(并且永远是同一个)和一个获得该实例的方法(类方法,我们常用getInstance命名~O(∩_∩)O~)。

当我们调用这个方法时,会有两种情况:1这个类的唯一实例方法不为空,返回这个唯一实例;2 这个类的唯一实例为空,创建它,并给全局使用。打个比方就好像一个项目里只有一个项目经理,产品的美工、后台、前端等小组的各个方案需要最终拍板,都会找这个项目经理,如果项目没有,我们就会指派一个人成为项目经理,并且以后一直担任下去。这样不管以后有多少个小组的多少个方案,我们只需要这一个项目经理就OK了,而不需要每次都请一个,浪费公司的资源,大家也会头痛。。。

单例模式可以节省被访问资源,特别是许多类都需要访问的资源,因为全局只有一个实例,不需要创建很多个新的,可以节省内存空间。另外只需要对这个单例修改就可以全局变化,就好像所有小组每天都要花钱,每天都要汇报,这些事每天都要找项目经理,但都是同一件事。同样的,有什么通知,只要告诉项目经理,所有小组成员都能很快知道。

但是单例模式也有缺陷。首先,由于单例属于全局的访问点,所以它不能被释放。会一直占据着那块空间。就好像一个项目没了个程序员,没什么大问题(像我这种彩笔),但是没了项目经理,那就不行了(不然你找谁签字负责?)这就产生一个问题==》在一个应用下我们不能创建太多的单例,否则这些单例就会侵占很大一部分内存空间。就好像一个项目,来了十几个经理。。。。老板会先砍死经理,再砍死自己(因为这些经理已经把公司的钱全花光了~)

另一个麻烦的地方就是,当有两个线程(A、B)并发时,会产生两个实例被同时创建出来。。。也就是单例的控制在并发情况下失效了。。。这就好像同时有两个小组找项目经理有事。。。不过有一种“双重检查枷锁机制”可以解决这个问题~

OK,接下来就是逻辑思路:

1 为单例对象实现一个静态实例,并初始化,然后设置成nil;

2实现一个实例构造方法检查上面的声明的静态实例是否为nill,如果是则新建并返回一个本类的实例;

3 重写allocWithZone方法,以保证接下来使用alloc或init创建出来的都是一个原来的实例(因为现在大部分都使用ARC模式,所以其它的方法重写就不提了)。


OK,下面就是代码实现的过程:

创建单例:

<span style="color: rgb(51, 51, 51); font-family: 宋体; font-size: 14px; line-height: 28px; text-indent: 28px;">#import <Foundation/Foundation.h></span>
@interface SDKsingleleton : NSObject
@property(retain,nonatomic)NSString *sdkway,*sdktitle;

+(SDKsingleleton *)currentSDK;
@end

实现单例的:

#import "SDKsingleleton.h"
@implementation SDKsingleleton
//有且只有一个静态属性
static SDKsingleleton *SDK;
+(SDKsingleleton *)currentSDK//实现单例
{
    if (SDK==nil) {
        SDK=[[SDKsingleleton alloc]init]; 
}
    return SDK;
}
+(id)allocWithZone:(struct _NSZone *)zone//重写allocwithZone方法
{
    if (SDK==nil) {
        SDK=[super allocWithZone:zone];
    }
    return SDK;
}
@end
 使用:在需要存值的地方,添加头文件,并生成实例:

     SDKsingleleton *sdk=[SDKsingleleton currentSDK];
     switch (indexPath.section) {
        case 0:
          sdk.sdktitle=@"哇卡卡卡卡";//存储数据到单例中(也可以在创建时添加数据)
          sdk.sdkway=@"WKKKK";
            break;
        case 1:
            ......
使用:调用单例内的数据传递给需要的页面:

#pragma mark调用推荐应用
-(void)OpenIntergrateWall{
     SDKsingleleton *sdk=[SDKsingleleton currentSDK];//调用实例(此时的单例包含数据)

    if ([sdk.sdkway isEqualToString:@"<span style="font-family: 宋体;">哇卡卡卡卡</span><span style="font-family: 宋体;">"]) {//此处调用了单例的数据进行判断接下来的程序运行</span>
        [singleLeton showMessage:YES didShowBlock:^{
            NSLog(@"单例数据已显示");
        } didDismissBlock:^{
            NSLog(@"单例数据显示失败");
        }];
    }else if
.........



这就是一个单例的简单运用。关于之前提到的 “双重检查锁”,大家可以看这篇博文里的介绍: 双重检查锁的方法。感谢他的方法介绍。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值