美文网首页
单例模式

单例模式

作者: helloyue | 来源:发表于2021-05-13 22:25 被阅读0次

    单例模式

    两种方式:

    1.GCD方式

    static id _instance;

    +(instancetype)sharedPerson {
    static dispatch_once_t onceToken;
    // GCD dispatch_once, 本身是线程安全的,保证整个程序中只会执行一次
    dispatch_once(&onceToken, ^{
    _instance = [[self alloc] init];
    });
    return _instance;
    }

    +(instancetype)allocWithZone:(struct _NSZone *)zone {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    _instance = [super allocWithZone:zone];
    });
    return _instance;
    }

    • (id)copyWithZone:(NSZone *)zone {
      return _instance;
      }

    • (id)mutableCopyWithZone:(NSZone *)zone {
      return _instance;
      }

    2.加锁方式:

    static id _instance;
    +(instancetype)allocWithZone:(struct _NSZone *)zone {
    //方案: 加互斥锁,解决多线程访问安全问题
    @synchronized(self){
    if (_instance == nil) {
    _instance = [super allocWithZone:zone];
    }
    }
    return _instance;
    }

    +(instancetype)sharedCar {
    @synchronized(self){
    if (_instance == nil) {
    _instance = [[self alloc] init];
    }
    }
    return _instance;
    }

    • (id)copyWithZone:(NSZone *)zone {
      return _instance;
      }

    • (id)mutableCopyWithZone:(NSZone *)zone {
      return _instance;
      }

    可以采用禁用方法:
    +(instancetype) new attribute((unavailable("OneTimeClass类只能初始化一次")));
    -(instancetype) copy attribute((unavailable("OneTimeClass类只能初始化一次")));
    -(instancetype) mutableCopy attribute((unavailable("OneTimeClass类只能初始化一次")));

    • (instancetype)init NS_UNAVAILABLE;
    • (instancetype)new NS_UNAVAILABLE;
    • (id)copy NS_UNAVAILABLE; // 没有遵循协议可以不写
    • (id)mutableCopy NS_UNAVAILABLE; // 没有遵循协议可以不写

    优缺点:
    优点:
    (1)在整个程序中只会实例化一次,所以在程序如果出了问题,可以快速的定位问题所在;(2)由于在整个程序中只存在一个对象,节省了系统内存资源,提高了程序的运行效率;

    缺点
    (1)不能被继承,不能有子类;
    (2)不易被重写或扩展(可以使用分类);
    (3)同时,由于单例对象只要程序在运行中就会一直占用系统内存,该对象在闲置时并不能销毁,在闲置时也消耗了系统内存资源;

    1:一个类只有一个对象,可能造成责任过重,在一定程度上违背了“单一职责原则”。
    2:由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
    3:滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。

    相关文章

      网友评论

          本文标题:单例模式

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