当前位置:懂科普 >

综合知识

> ios单例模式怎么写 如何写一个简单的单例模式

ios单例模式怎么写 如何写一个简单的单例模式

1.如何写一个简单的单例模式

一、基本的实现思路:

ios单例模式怎么写 如何写一个简单的单例模式

单例的实现主要是通过以下两个步骤:

1、将该类的构造方法定义为私有方法,这样其他处的代码就无法通过调用该类的构造方法来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例;

2、在该类内提供一个静态方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用。

二、示范如下:

1、枚举实现单例:

2、懒汉式线程不安全:

3、懒汉式线程安全:

4、饿汉式:

5、双重校验锁:

6、静态内部类:

扩展资料:

一、单列模式简介:

单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。使用工厂方法来限制实例化过程。这个方法应该是静态方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义。

二、懒汉与饿汉:

1、懒汉方式:指全局的单例实例在第一次被使用时构建。

2、饿汉方式:指全局的单例实例在类装载时构建。

三、单例模式的三要点:

1、某个类只能有一个实例。

2、它必须自行创建这个实例。

3、它必须自行向整个系统提供这个实例。

四、优缺点:

1、优点:

①实例控制:单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。

②灵活性:因为类控制了实例化过程,所以类可以灵活更改实例化过程。

2、缺点:

①开销:虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。

②可能的开发混淆:使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。

③对象生存期:不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。

参考资料:百度百科单列模式

2.开发中如何使用单例 ios

为你解答。

第一、基本概念单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。

通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问。第二、在IOS中使用单例模式的情况1.如果说创建一个对象会耗费很多系统资源,那么此时采用单例模式,因为只需要一个实例,会节省alloc的时间2.在IOS开发中,如果很多模块都要使用同一个变量,此时如果把该变量放入单例类,则所有访问该变量的调用变得很容易,否则,只能通过一个模块传递给另外一个模块,这样增加了风险和复杂度第三、创建单例模式的基本步骤1.声明一个单例对象的静态实例,并初始化为nil2.声明一个类的工厂方法,生成一个该类的实例,并且只会生成一个3.覆盖allcoWithZone方法,确保用户在alloc 时,不会产生一个多余的对象4.实现NSCopying协议,覆盖release,autorelease,retain,retainCount方法,以确保只有一个实例化对象5.在多线程的环境中,注意使用@synchronized关键字 [cpp] view plaincopyprint?// // UserContext.h // SingleDemo // // Created by andyyang on 9/30/13. // Copyright (c) 2013 andyyang. All rights reserved. // #import @interface UserContext : NSObject @property (nonatomic,retain) NSString *username; @property(nonatomic,retain)NSString *email; +(id)sharedUserDefault; @end [cpp] view plaincopyprint?// // UserContext.m // SingleDemo // // Created by andyyang on 9/30/13. // Copyright (c) 2013 andyyang. All rights reserved. // #import "UserContext.h" static UserContext *singleInstance=nil; @implementation UserContext +(id)sharedUserDefault { if(singleInstance==nil) { @synchronized(self) { if(singleInstance==nil) { singleInstance=[[[self class] alloc] init]; } } } return singleInstance; } + (id)allocWithZone:(NSZone *)zone; { NSLog(@"HELLO"); if(singleInstance==nil) { singleInstance=[super allocWithZone:zone]; } return singleInstance; } -(id)copyWithZone:(NSZone *)zone { NSLog(@"hello"); return singleInstance; } -(id)retain { return singleInstance; } - (oneway void)release { } - (id)autorelease { return singleInstance; } - (NSUInteger)retainCount { return UINT_MAX; }@end [cpp] view plaincopyprint?#import #import "UserContext.h" int main(int argc, const char * argv[]) { @autoreleasepool { UserContext *userContext1=[UserContext sharedUserDefault]; UserContext *userContext2=[UserContext sharedUserDefault]; UserContext *userContext3=[[UserContext alloc] init]; UserContext *userContext4=[userContext1 copy]; // insert code here。

NSLog(@"Hello, World!"); } return 0; } 在开发中我们可以利用ios提供的方法来实现单例模式:SYNTHESIZE_SINGLETON_FOR_CLASS(MyClassName);将该语句置于@implementation MyClassName声明后,这样你的类自动会变成单例。内容来自于richard_如风的博客。

3.单例模式代码怎么写

单例模式(Singleton) ,属于最常见的设计模式之一,大部分系统都会用到,目的是为了维护系统中唯一的一个实例。

可分为eager模式,示例代码如下: Java代码 1.class EagerSingleton{ 2. private static final EagerSingleton m_instance = new EagerSingleton(); 3. private EagerSingleton(){} 4. public static EagerSingleton getInstance(){ 5. return m_instance; 6. } 7.} class EagerSingleton{ private static final EagerSingleton m_instance = new EagerSingleton(); private EagerSingleton(){} public static EagerSingleton getInstance(){ return m_instance; } } 和 lazy模式,示例代码如下: Java代码 1.class LazySingleton{ 2. private static LazySingleton m_instance = null; 3. private LazySingleton(){} 4. public synchronized static getInstance(){ 5. if(m_instance == null){ 6. m_instance = new LazySingleton(); 7. } 8. return m_instance; 9. } 10.} class LazySingleton{ private static LazySingleton m_instance = null; private LazySingleton(){} public synchronized static getInstance(){ if(m_instance == null){ m_instance = new LazySingleton(); } return m_instance; } } java源码中,Runtime.getRuntime()就是单例的一个例子。 单例模式的精神就是整个系统中维护一个实例,推广开来,如果在一个系统中需要维护多个示例,那么就产生了多例模式(multiton)。

多例模式(Multiton) ,通过聚集对象了保留自身的多个示例,根据客户端的参数返回所需要的实例。 示例代码如下: Java代码 1.class Multiton{ 2. private final int INSTANCE_SIZE = 10; 3. private static Map instances = new HashMap(INSTANCE_SIZE); 4. private String name; 5. private Multiton(){} 6. private Multiton(String name){ 7. this.name = name; 8. } 9. public synchronized static getInstance(String name){ 10. if(instances.containsKey(name)){ 11. return instances.get(name); 12. } 13. else{ 14. ins = new Multiton(name); 15. instances.put(name, ins); 16. return ins; 17. } 18. } 19.} class Multiton{ private final int INSTANCE_SIZE = 10; private static Map instances = new HashMap(INSTANCE_SIZE); private String name; private Multiton(){} private Multiton(String name){ this.name = name; } public synchronized static getInstance(String name){ if(instances.containsKey(name)){ return instances.get(name); } else{ ins = new Multiton(name); instances.put(name, ins); return ins; } } } [nextpage] 一个实用的例子就是KeyGenerator, 示例代码如下: Java代码 1.class KeyGenerator{ 2. private final int POOL_SIZE = 20; 3. private static Map instances = new HashMap(16); 4. private KeyInfo keyinfo; 5. private KeyGenerator(){} 6. private KeyGenerator(String keyName){ 7. this.keyinfo = new KeyInfo(POOL_SIZE, keyName); 8. } 9. public synchronized static getInstance(String keyName){ 10. if(instances.containsKey(keyName)){ 11. return (KeyGenerator)instances.get(keyName); 12. } 13. else{ 14. keyGen = new KeyGenerator(keyName); 15. instances.put(name, keyGen); 16. return keyGen; 17. } 18. } 19. public synzhronized int getNextKey(){ 20. return keyinfo.getNextKey(); 21. } 22. } class KeyGenerator{ private final int POOL_SIZE = 20; private static Map instances = new HashMap(16); private KeyInfo keyinfo; private KeyGenerator(){} private KeyGenerator(String keyName){ this.keyinfo = new KeyInfo(POOL_SIZE, keyName); } public synchronized static getInstance(String keyName){ if(instances.containsKey(keyName)){ return (KeyGenerator)instances.get(keyName); } else{ keyGen = new KeyGenerator(keyName); instances.put(name, keyGen); return keyGen; } } public synzhronized int getNextKey(){ return keyinfo.getNextKey(); } }。

4.单例模式代码怎么写

单例模式(Singleton) ,属于最常见的设计模式之一,大部分系统都会用到,目的是为了维护系统中唯一的一个实例。

可分为eager模式,示例代码如下: Java代码 1.class EagerSingleton{ 2. private static final EagerSingleton m_instance = new EagerSingleton(); 3. private EagerSingleton(){} 4. public static EagerSingleton getInstance(){ 5. return m_instance; 6. } 7.} class EagerSingleton{ private static final EagerSingleton m_instance = new EagerSingleton(); private EagerSingleton(){} public static EagerSingleton getInstance(){ return m_instance; } } 和 lazy模式,示例代码如下: Java代码 1.class LazySingleton{ 2. private static LazySingleton m_instance = null; 3. private LazySingleton(){} 4. public synchronized static getInstance(){ 5. if(m_instance == null){ 6. m_instance = new LazySingleton(); 7. } 8. return m_instance; 9. } 10.} class LazySingleton{ private static LazySingleton m_instance = null; private LazySingleton(){} public synchronized static getInstance(){ if(m_instance == null){ m_instance = new LazySingleton(); } return m_instance; } } java源码中,Runtime.getRuntime()就是单例的一个例子。 单例模式的精神就是整个系统中维护一个实例,推广开来,如果在一个系统中需要维护多个示例,那么就产生了多例模式(multiton)。

多例模式(Multiton) ,通过聚集对象了保留自身的多个示例,根据客户端的参数返回所需要的实例。 示例代码如下: Java代码 1.class Multiton{ 2. private final int INSTANCE_SIZE = 10; 3. private static Map instances = new HashMap(INSTANCE_SIZE); 4. private String name; 5. private Multiton(){} 6. private Multiton(String name){ 7. this.name = name; 8. } 9. public synchronized static getInstance(String name){ 10. if(instances.containsKey(name)){ 11. return instances.get(name); 12. } 13. else{ 14. ins = new Multiton(name); 15. instances.put(name, ins); 16. return ins; 17. } 18. } 19.} class Multiton{ private final int INSTANCE_SIZE = 10; private static Map instances = new HashMap(INSTANCE_SIZE); private String name; private Multiton(){} private Multiton(String name){ this.name = name; } public synchronized static getInstance(String name){ if(instances.containsKey(name)){ return instances.get(name); } else{ ins = new Multiton(name); instances.put(name, ins); return ins; } } } [nextpage] 一个实用的例子就是KeyGenerator, 示例代码如下: Java代码 1.class KeyGenerator{ 2. private final int POOL_SIZE = 20; 3. private static Map instances = new HashMap(16); 4. private KeyInfo keyinfo; 5. private KeyGenerator(){} 6. private KeyGenerator(String keyName){ 7. this.keyinfo = new KeyInfo(POOL_SIZE, keyName); 8. } 9. public synchronized static getInstance(String keyName){ 10. if(instances.containsKey(keyName)){ 11. return (KeyGenerator)instances.get(keyName); 12. } 13. else{ 14. keyGen = new KeyGenerator(keyName); 15. instances.put(name, keyGen); 16. return keyGen; 17. } 18. } 19. public synzhronized int getNextKey(){ 20. return keyinfo.getNextKey(); 21. } 22. } class KeyGenerator{ private final int POOL_SIZE = 20; private static Map instances = new HashMap(16); private KeyInfo keyinfo; private KeyGenerator(){} private KeyGenerator(String keyName){ this.keyinfo = new KeyInfo(POOL_SIZE, keyName); } public synchronized static getInstance(String keyName){ if(instances.containsKey(keyName)){ return (KeyGenerator)instances.get(keyName); } else{ keyGen = new KeyGenerator(keyName); instances.put(name, keyGen); return keyGen; } } public synzhronized int getNextKey(){ return keyinfo.getNextKey(); } }。

5.如何正确地写出单例模式

当被问到要实现一个单例模式时,很多人的第一反应是写出如下的代码,包括教科书上也是这样教我们的。

1234567891011public class Singleton {private static Singleton instance;private Singleton (){}public static Singleton getInstance () {if (instance == null ) {instance = new Singleton();}return instance;}}这段代码简单明了,而且使用了懒加载模式,但是却存在致命的问题。当有多个线程并行调用 getInstance() 的时候,就会创建多个实例。

也就是说在多线程下不能正常工作。懒汉式,线程安全为了解决上面的问题,最简单的方法是将整个 getInstance() 方法设为同步(synchronized)。

123456public static synchronized Singleton getInstance () {if (instance == null ) {instance = new Singleton();}return instance;}虽然做到了线程安全,并且解决了多实例的问题,但是它并不高效。因为在任何时候只能有一个线程调用 getInstance() 方法。

但是同步操作只需要在第一次调用时才被需要,即第一次创建单例实例对象时。这就引出了双重检验锁。

双重检验锁双重检验锁模式(double checked locking pattern),是一种使用同步块加锁的方法。程序员称其为双重检查锁,因为会有两次检查 instance == null ,一次是在同步块外,一次是在同步块内。

为什么在同步块内还要再检验一次?因为可能会有多个线程一起进入同步块外的 if,如果在同步块内不进行二次检验的话就会生成多个实例了。12345678910public static Singleton getSingleton () {if (instance == null ) { //Single Checkedsynchronized (Singleton.class) {if (instance == null ) { //Double Checkedinstance = new Singleton();}}}return instance ;}这段代码看起来很完美,很可惜,它是有问题。

主要在于 instance = new Singleton() 这句,这并非是一个原子操作,事实上在 JVM 中这句话大概做了下面 3 件事情。给 instance 分配内存调用 Singleton 的构造函数来初始化成员变量将instance对象指向分配的内存空间(执行完这步 instance 就为非 null 了)但是在 JVM 的即时编译器中存在指令重排序的优化。

也就是说上面的第二步和第三步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是 1-3-2。如果是后者,则在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,然后顺理成章地报错。

我们只需要将 instance 变量声明成 volatile 就可以了。 class Singleton {private volatile static Singleton instance; //声明成 volatileprivate Singleton (){}public static Singleton getSingleton () {if (instance == null ) {synchronized (Singleton.class) {if (instance == null ) {instance = new Singleton();}}}return instance;}}有些人认为使用 volatile 的原因是可见性,也就是可以保证线程在本地不会存有 instance 的副本,每次都是去主内存中读取。

但其实是不对的。使用 volatile 的主要原因是其另一个特性:禁止指令重排序优化。

也就是说,在 volatile 变量的赋值操作后面会有一个内存屏障(生成的汇编代码上),读操作不会被重排序到内存屏障之前。比如上面的例子,取操作必须在执行完 1-2-3 之后或者 1-3-2 之后,不存在执行到 1-3 然后取到值的情况。

从「先行发生原则」的角度理解的话,就是对于一个 volatile 变量的写操作都先行发生于后面对这个变量的读操作(这里的“后面”是时间上的先后顺序)。但是特别注意在 Java 5 以前的版本使用了 volatile 的双检锁还是有问题的。

其原因是 Java 5 以前的 JMM (Java 内存模型)是存在缺陷的,即时将变量声明成 volatile 也不能完全避免重排序,主要是 volatile 变量前后的代码仍然存在重排序问题。这个 volatile 屏蔽重排序的问题在 Java 5 中才得以修复,所以在这之后才可以放心使用 volatile。

相信你不会喜欢这种复杂又隐含问题的方式,当然我们有更好的实现线程安全的单例模式的办法。饿汉式 static final field这种方法非常简单,因为单例的实例被声明成 static 和 final 变量了,在第一次加载类到内存中时就会初始化,所以创建实例本身是线程安全的。

12345678910public class Singleton {//类加载时就初始化private static final Singleton instance = new Singleton();private Singleton (){}public static Singleton getInstance (){return instance;}}这种写法如果完美的话,就没必要在啰嗦那么多双检锁的问题了。缺点是它不是一种懒加载模式(lazy initialization),单例会在加载类后一开始就被初始化,即使客户端没有调用 getInstance()方法。

饿汉式的创建方式在一些场景中将无法使用:譬如 Singleton 实例的创建是依赖参数或者配置文件的,在 getInstance() 之前必须调用某个方法设置参数给它,那样这种单例写法就无法使用了。静态内部类 static nested class我比较倾向于使用静态内部类的方法,这种方法也是《Effective Java》上所推荐的。

123456789public class Singleton {private static class SingletonHolder {private static final Singleton INSTANCE = new Singleton();}private Singleton (){}public 。

6.如何写一个Singleton(单例模式)

使用线程单列模式获得org.hibernate.Session对象

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

public class {

private static Configuration conf;

private static SessionFactory sf;

private static ThreadLocal<Session> tl = new ThreadLocal<Session>();

//ThreadLocal<Session>;内部是Map结构,用线程id作为key值,用来存放多个Session对象

static {

conf = new Configuration();

conf.configure();

sf = conf.buildSessionFactory();

}

public static Session getSession() {

Session session = tl.get();//以当前线程的id作为Key,取出一个Session对象

if (session == null) {

session = sf.openSession();//如果为空,则获取一个新的Session对象,并存入tl中

tl.set(session);

}

return session;

}

public static void closeSession() {//关闭一个session

Session session = tl.get();//以当前线程的id作为Key,取出一个Session对象

if (session != null) {//如果不为空,怎关闭

session.close();

tl.set(null);

}

}

}

7.单例模式怎样写

class StringManager {

private static StringManager instance;

private Map beanMap;

private StringManager() {

beanMap = new HashMap();

}

public static StringManager getInstance() {

if (instance == null) {

instance = new StringManager();

}

return instance;

}

public Object getBean(String beanName) {

return beanMap.get(beanName);

}

}

标签: 单例 模式 ios
  • 文章版权属于文章作者所有,转载请注明 https://dongkepu.com/zonghezhishi/po7mz7.html