单例的各种写法

单例模式,顾名思义,在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

单例模式最初的定义出现于《设计模式》(艾迪生维斯理, 1994):“保证一个类仅有一个实例,并提供一个访问它的全局访问点。”

oc中常用于 文件,数据库等。

最基本的oc写法:

-(instancetype)defaultInstance
{
    static InstanceType instance;
    if (instance == nil)
    {
        instance = [[InstanceType alloc]init];
    }
    return instance;
}

但是这样的写法是有问题的,因为我们没有对其他初始化方法进行重写。于是在使用[InstanceType defaultInstance] 和[InstanceType alloc]init

得到的对象就不是同一个。

在重写方法之前 我们必须清楚一件事情,alloc内部会调用allocWithZone 在自定义对象的copy中会调用copyWithZone和allocWithZone

那么现在我们开始重写。

-(id)copyWithZone:(NSZone *)zone
{
    Manager * manager = [[Manager alloc]init];
    return manager;
}
+(id)allocWithZone:(struct _NSZone *)zone
{
    NSLog(@"%@",@"---");
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super allocWithZone:zone];
    });
    return instance;
}

调用alloc,copy的代码

-(void)newSingleTon
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
       NSLog(@"%@",[Manager getManager]);
    });

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        Manager * manager = [Manager getManager];
        manager.name = @"sss";
        NSLog(@"manager--%@",manager);
        NSLog(@"%@",[manager copy]);
        NSLog(@"%@",[[Manager alloc]init]);
    });
}

此时运行代码的结果为:

2015-09-17 11:09:16.080 02GCDMakeSingleton[970:53274] <Manager: 0x7fa893fa4530>
2015-09-17 11:09:16.080 02GCDMakeSingleton[970:53275] manager--<Manager: 0x7fa893fa4530>
2015-09-17 11:09:16.081 02GCDMakeSingleton[970:53275] <Manager: 0x7fa893fa4530>
2015-09-17 11:09:16.081 02GCDMakeSingleton[970:53275] <Manager: 0x7fa893fa4530>

结果表示 经过重写之后我们可以看到 得到的对象是一个对象。

单例就讨论到这里。

时间: 2024-11-15 02:29:57

单例的各种写法的相关文章

C# 单例3种写法

public class Singleton { private static Singleton _instance = null; private Singleton(){} public static Singleton CreateInstance() { if(_instance == null) { _instance = new Singleton(); } return _instance; } } 第二种考虑了线程安全,不过有点烦,但绝对是正规写法,经典的一叉 public c

Unity 单例写法

https://www.cnblogs.com/SHOR/p/5192046.html 借鉴自:http://www.cnblogs.com/CodeCabin/p/unity_global_manager.html 实现复杂一些的全局控制,如切换游戏关卡等操作,更常用的方式是使用单例类.单例类的实现又分为两种: 继承自MonoBehaviour的单例类 纯C#的单例类 前者的优点是: 可以在Inspector中显示,便于赋值和查看变量等: 可以利用MonoBehaviour的接口: 可以使用C

单例类多线程

作为设计模式理论中的Helloworld,相信学习java语言的人,都应该听说过单例模式.单例模式作为对象的一种创建模式,它的作用是确保某一个类在整个系统中只有一个实例,而且自行实例化并向整个系统提供这个实例. 由此可见,单例模式具有以下的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一的实例. 单例类必须给所有其他对象提供这一实例. 由于Java语言的特点,使得单例模式在Java语言的实现上有自己的特点.这些特点主要表现在单例类如何将自己实例化. 饿汉式单例类 饿汉式单例类是在Ja

C++ Singleton (单例) 模式最优实现

参考:http://blog.yangyubo.com/2009/06/04/best-cpp-singleton-pattern/ 索引 静态化并不是单例 (Singleton) 模式 饿汉模式 懒汉模式 (堆栈-粗糙版) 懒汉模式 (局部静态变量-最佳版) 范例代码和注意事项 (最优实现) 扩展阅读 参考资料 我非常赞成合理的使用 设计模式 能让代码更容易理解和维护, 不过我自己除了简单的 单例 (Singleton) 模式 外, 其它都很少用 :-) 可耻的是, 直到前段时间拜读了 C++

【Java】设计模型-五种单例模型

一. 什么是单例模式 只需要某个类同时保留一个对象,不希望有更多对象,此时,我们则应考虑单例模式的设计. 单例模式的主要作用是保证在Java程序中,某个类只有一个实例存在. 单例模式有很多好处,它能够避免实例对象的重复创建,不仅可以减少每次创建对象的时间开销,还可以节约内存空间: 能够避免由于操作多个实例导致的逻辑错误.如果一个对象有可能贯穿整个应用程序,而且起到了全局统一管理控制的作用,那么单例模式也许是一个值得考虑的选择. 二. 单例模式的特点 1. 单例模式只能有一个实例. 2. 单例类必

Java-----关于单例设计模式

1. 单例模式DCL写法 单例设计模式中,有一种双重检查锁的写法, 也就是所谓的懒汉式 class Single{ private static Single sSingle; private Single() {} public static Single getInstance() { if(sSingle == null) { synchronized(Single.class) { if(sSingle == null) { sSingle = new Single(); } } } r

单例写法 转

如何正确地写出单例模式 1.懒汉式,线程不安全 这段代码简单明了,而且使用了懒加载模式,但是却存在致命的问题.当有多个线程并行调用 getInstance() 的时候,就会创建多个实例.也就是说在多线程下不能正常工作 public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == nu

有一鲜为人知的单例写法-ThreadLocal

还有一鲜为人知的单例写法-ThreadLocal 源码范例 当我阅读FocusFinder和Choreographer的时候,我发现这两类的单例实现和我们平常用双重检查锁很不一样.而是用来一个ThreadLocal,这个也可以实现单例啊,那这个与双重检查锁实现的单例有什么区别呢? 1.FocusFinder /** * The algorithm used for finding the next focusable view in a given direction * from a view

Egret中的三种单例写法

1 普通的单例写法 class Single{ private static instance:Single; public static getInstance():Single{ if(this.instance == null){ this.instance = new Single(); } return this.instance; } public run(){ } } Single.getInstance().run(); 2 Module写法.仿照的Egret中Res资源类写法.