关于单例模式

原创 2013年12月02日 17:01:46
+ (NoteDAO *)sharedManager
{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        
        sharedManager = [[self alloc] init];
        [sharedManager createEditableCopyOfDatabaseIfNeeded];
        
    });
    return sharedManager;
}


dispath_once(dispatch_once_t *predicate, dispatch_block_t block),第一个参数用于确认是否已执行过第二个参数block,保证第二个参数block只执行一次。用于创建单例

今天碰到以上一段代码,看了文档也找了一篇文章。以下


无论是爱还是恨,你都需要单例。实际上每个iOS或Mac OS应用都至少会有UIApplicationNSApplication.
什么是单例呢?Wikipedia是如此定义的:
在软件工程中,单例是一种用于实现单例的数学概念,即将类的实例化限制成仅一个对象的设计模式。
或者我的理解是:
单例是一种类,该类只能实例化一个对象。
    尽管这是单例的实际定义,但在Foundation框架中不一定是这样。比如NSFileMangerNSNotificationCenter,分别通过它们的类方法defaultManagerdefaultCenter获取。尽管不是严格意义的单例,这些类方法返回一个可以在应用的所有代码中访问到的类的共享实例。在本文中我们也会采用该方法。
    使用Objective-C实现单例模式的最佳方式向来有很多争论,开发者(包括Apple在内)似乎每几年就会改变他们的想法。当Apple引入了Grand Central Dispatch (GCD)(Mac OS 10.6和iOS4.0),他们也引入了一个很适合用于实现单例模式的函数。
    该函数就是dispatch_once
void dispatch_once( dispatch_once_t *predicate, dispatch_block_t block);
    该函数接收一个dispatch_once用于检查该代码块是否已经被调度的谓词(是一个长整型,实际上作为BOOL使用)。它还接收一个希望在应用的生命周期内仅被调度一次的代码块,对于本例就用于shared实例的实例化。
dispatch_once不仅意味着代码仅会被运行一次,而且还是线程安全的,这就意味着你不需要使用诸如@synchronized之类的来防止使用多个线程或者队列时不同步的问题。
    Apple的GCD Documentation证实了这一点:
如果被多个线程调用,该函数会同步等等直至代码块完成。
    实际要如何使用这些呢?
    好吧,假设有一个AccountManager类,你想在整个应用中访问该类的共享实例。你可以按如下代码简单实现一个类方法:
+ (AccountManager *)sharedManager { 
    static AccountManager *sharedAccountManagerInstance = nil; 

    static dispatch_once_t predicate; dispatch_once(&predicate, ^{       
          sharedAccountManagerInstance = [[self alloc] init]; 
    });

    return sharedAccountManagerInstance; 

}
    这就意味着你任何时候访问共享实例,需要做的仅是:
AccountManager *accountManager = [AccountManager sharedManager];
    就这些,你现在在应用中就有一个共享的实例,该实例只会被创建一次。
    该方法有很多优势: 
           1 线程安全
           2 很好满足静态分析器要求
           3 和自动引用计数(ARC)兼容 
           4 仅需要少量代码
    该方法的劣势就是它仍然运行创建一个非共享的实例:
AccountManager *accountManager = [[AccountManager alloc] init];
    有些时候你希望有这种行为,但如果正在想要的是仅一个实例被实例化就需要注意这点

总结:1.这个方法可以在创建单例或者某些初始化动作时使用,以保证其唯一性。2.该方法是线程安全的,所以请放心大胆的在子线程中使用。(前提是你的dispatch_once_t *predicate对象必须是全局或者静态对象。这一点很重要,如果不能保证这一点,也就不能保证该方法只会被执行一次。)

单例模式的两种实现方式

1.   饿汉模式: #include using namespace std; class Singleton { public: static Singleton& getInst (void...
  • meetings
  • meetings
  • 2015年08月06日 16:27
  • 916

单例模式:为什么要双重检测

http://blog.sina.com.cn/s/blog_6b6468720100kpif.html 3.3  延迟加载的思想         单例模式的懒汉式实现方式体现了延...
  • wscdylzjy
  • wscdylzjy
  • 2015年03月26日 18:50
  • 6190

单例模式在多线程中的安全性研究

关于一般单例模式的创建和分析在我的另一篇博客《Java设计模式——单件模式》中有详细说明。只是在上篇博客中的单例是针对于单线程的操作,而对于多线程却并不适用,本文就从单例模式与多线程安全的角度出发,讲...
  • u013761665
  • u013761665
  • 2016年04月06日 14:13
  • 2766

一个单例模式的简单例子

ex1: public class Singleton    {        private static final Singleton singleton = null;           p...
  • silence1214
  • silence1214
  • 2009年03月29日 14:56
  • 23515

C#单例模式的几种实现方式

C#单例模式的几种实现方式
  • yanlovehan
  • yanlovehan
  • 2016年11月09日 10:07
  • 2164

单例模式的三种常用的形式

自己做下笔记: //单例模式:他的应用场景—如果多个程序要操作一个对象中的数据,那么就要保证只有一个对象。 //饿汉式 publicclassSingle {     privatesta...
  • jiyidehao
  • jiyidehao
  • 2016年02月28日 12:26
  • 491

单例模式的自动析构

总所周知,单例模式如果不主动调用,在进程结束时是不会析构的,而是仅仅把内存释放掉而已 所以,如果希望在析构时进行某些操作,在进程结束前,可以主动调用析构函数,如下面类中的delMe函数(xSingl...
  • mengmingqiang
  • mengmingqiang
  • 2011年08月31日 15:43
  • 2742

设计模式学习笔记---单例模式(Java版)

GOF23(Group of  four) 创建型模式 单例模式,工厂模式,抽象工厂模式,建造者模式,原型模式。 结构型模式 适配器模式,桥接模式,装饰模式,组合模式,外观模式,享元模式,代理模式...
  • scgaliguodong123_
  • scgaliguodong123_
  • 2015年01月09日 09:30
  • 1163

Java中用单例模式有什么好处

Java Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。 使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(...
  • huanbia
  • huanbia
  • 2017年05月12日 10:05
  • 2397

Selenium使用单例模式

在项目中使用Selenium进行自动化,非常自然想到用单例对WebDriver进行管理,出于如下考虑:         1)提高成功率。多个实例会使得出现多个浏览器窗口,界面识别会出现问题,影响成功...
  • wanglian2017
  • wanglian2017
  • 2017年06月13日 21:58
  • 364
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于单例模式
举报原因:
原因补充:

(最多只允许输入30个字)