美文网首页
iOS 单例模式使用

iOS 单例模式使用

作者: 苏宇lovecc | 来源:发表于2016-06-23 20:38 被阅读114次

    注:只介绍怎么使用,至于其他的方面,google去吧。

    1. 实现步骤:

      1. 为单例对象声明一个静态实例,并初始化,然后设置成nil。
      2. 声明并实现一个类方法,检查上面声明的静态实例是否为nil;如果是,则将静态变量初始化为本类的实例。
      3. 重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不会产生一个新实例。
      4. 非ARC(MRC)模式下,实现copyWithZone,release和autorelease等方面。
    2. 具体代码
      具体的实现方法有2种。假设有个类UserInfo需要使用单例模式。
      首先,在UserInfo.h文件中,需要提供一个标准的实例访问接口。

    //该类方法的名称一般以 share,default,main为前缀
    +(UserInfo *)shareUserInfo;
    

    第1种方法:

    #import "UserInfo.h"
    
    //定义一个静态变量,用于接收实例对象并初始化为nil
    static UserInfo *singleInstance = nil;
    
    @implementation UserInfo
    
    //在多线程的情况下,多个任务会同时执行,它们的执行方式是抢占式的,所以为保证线程安全,增加互斥锁
    + (UserInfo *)shareUserInfo {
        @synchronized (self) {
            if (singleInstance == nil) {
                singleInstance = [[UserInfo alloc] init];
            }
        }
        return singleInstance;
    }
    
    //使用单例时,不想再实例化出其它的对象,可以重写 allocWithZone: 
    + (instancetype)allocWithZone:(struct _NSZone *)zone {
        @synchronized (self) {
            if (singleInstance == nil) {
                singleInstance = [super allocWithZone:zone];
            }
        }
        return singleInstance;
    }
    
    @end
    

    第2种方法:

    #import "UserInfo.h"
    
    static UserInfo *singleInstance = nil;
    
    @implementation UserInfo
    
    //1.dispatch_once可以在创建单例或者某些初始化动作时使用,以保证其唯一性。
    //2.该方法是线程安全的,所以请放心大胆地在子线程中使用。前提是你的dispatch_once_t *predicate对象必须是全局或者静态对象。这一点很重要,如果不能保证这一点,也就不能保证该方法只会被执行一次。
    + (UserInfo *)shareUserInfo {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            singleInstance = [[UserInfo alloc] init];
        });
        return singleInstance;
    }
    
    + (instancetype)allocWithZone:(struct _NSZone *)zone {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            singleInstance = [super allocWithZone:zone];
        });
        return singleInstance;
    }
    
    @end
    

    另外,在非ARC(MRC)模式下,需要重写以下方法

    //禁止copy
    +(id)copyWithZone:(struct _NSZone *)zone{
        return self;
    }
    //retain后引用计数+1
    -(instancetype)retain{
        return self;
    }
    //release后引用计数-1
    -(oneway void)release{
        //什么都不做
    }
    //自动释放池
    -(instancetype)autorelease{
        return self;
    }
    //查看引用计数器
    -(NSUInteger)retainCount{
        //返回无穷大的数,表示不能release
        return NSIntegerMax;
    }
    

    相关文章

      网友评论

          本文标题:iOS 单例模式使用

          本文链接:https://www.haomeiwen.com/subject/wycodttx.html