zoukankan      html  css  js  c++  java
  • Objective-C设计模式——单例Singleton(对象创建)

    单例

    和其它语言的单例产不多,可以说是最简单的一种设计模式了。但是有几个点需要注意下,单例就是一个类只有一个实例。

    所以我们要想办法阻止该类产生别的实例,一般语言中都会将构造函数写为private。但是OC中的函数并没有限定符,所以我们需要用一些小技巧来屏蔽这一点。

    应用场景

    类只能有一个实例,而且必须从一个为人熟知的访问点对其进行访问,比如工厂方法。

    这个唯一的实例只能通过类的子类化进行扩展,而且扩展的对象不会破坏客户端代码。

    注意

    1.OC中单例的实例变量要定义在.m文件

    2.OC中单例需要重载allocWithZone:和copyWithZone:方法来防止创建别的实例。

    3.单例创建要注意线程安全,不然就可能出现多个实例。

    注意问题将会在Demo中讲解

    Demo

    首先先来看一个最常规,的不严谨的单例实现:

    @implementation Singleton
    
    static Singleton *sharedInstance;
    
    -(Singleton *)sharedInstance
    {
        if(sharedInstance)
        {
            sharedInstance = [Singleton new];
        }
        return sharedInstance;
    }
    
    @end

    这看似好像是可以得到单例对象了,但是这可以说是单例的一种变形。绝不能说这就是单例,因为我们可以轻松地通过其他方式来创建对象。

    所以我们还要我修改allocWithZone:和copyWithZone:方法(alloc 和 copy 方法实际上就是调用这两个方法)

    -(id)copyWithZone:(NSZone *)zone
    {
        return [[self class] sharedInstance];
    }
    
    +(id)allocWithZone:(struct _NSZone *)zone
    {
        return [self sharedInstance];
    }

    可是这就出现另一个问题,在sharedInstance方法里面我们实际调用过allocWithZone:(new 调用 alloc),但是它的alloc被我们重写了,这就会出现错误。所以我们需要修改sharedInstance方法

    +(Singleton *)sharedInstance
    {
        if(sharedInstance)
        {
            sharedInstance = [[super allocWithZone:NULL] init];
        }
        return sharedInstance;
    }

    这样就可以顺利的返回单例了,而且无法通过其它方式产生实例对象。

    看似完美了实际还会有问题出现,因为现在是非线程安全的,可能存在同一时间创建多个实例的情况,所以修改如下

    +(instancetype)sharedInstance
    {
        static dispatch_once_t once;
        dispatch_once(&once, ^{
            sharedInstance = [[super allocWithZone:NULL] init];
        });
        return sharedInstance;
    }

    客户端代码如下:

            Singleton *singleton = [Singleton sharedInstance];
            Singleton *singleton2 = [[Singleton alloc] init];
            Singleton *singleton3 = [singleton copy];
     
            [singleton print];
            [singleton2 print];
            [singleton3 print];

    输出结果:

    2015-07-21 21:10:32.797 Singleton[42537:10347987] 0x7fff5fbff7a8
    2015-07-21 21:10:32.798 Singleton[42537:10347987] 0x7fff5fbff7a8
    2015-07-21 21:10:32.798 Singleton[42537:10347987] 0x7fff5fbff7a8

    可以看到内存都指向了同一地址。

  • 相关阅读:
    RNN-2-前向传播、BPTT反向传播
    RNN-1-参数共享、网络的展开、常见应用
    被围绕的区域
    语言模型的评价方法
    个性化推荐系统
    推荐系统-CTR-Wide&Deep
    推荐系统-CTR-总结
    推荐系统-CTR-PNN
    Local variable flag defined in an enclosing scope must be final or effective
    2.两数相加
  • 原文地址:https://www.cnblogs.com/madpanda/p/4665638.html
Copyright © 2011-2022 走看看