您的位置:首页 > 移动开发 > Swift

Java/Swift 单例模式的多种写法

2016-07-01 15:20 369 查看
        设计模式的书本上一般是这样写:
         public final class SingleTon {
                  private static SingleTon sInstance;     
                  public static SingleTon getInstance() {
                            if (sInstance == null) {
                                     sInstance = new SingleTon();
                            }
                            return sInstance;
                   }
        }
       仔细看这几行代码, 能发现什么问题吗?  脑洞大开一下。

        1. 在外部类中可以new出SingleTon对象。
        2. 多线程时怎么办? 可能生成多个SingleTon实例, 我们想到了锁。 

         public final class SingleTon {
                  private static SingleTon sInstance;   
                  private SingleTon() {
                         //将构造函数声明成私有函数, 从而在类外部无法实例化该类
                  }  
                  public synchronized static SingleTon getInstance() {
                            if (sInstance == null) {
                                     sInstance = new SingleTon();
                            }
                            return sInstance;
                   }
        }
        添加synchronized关键字后实际上是SingleTon.class上锁, 但对函数上锁的颗粒度较大, 影响多线程并发的性能, 实际上我们只需要对new对象上锁, 读对象时不上锁。 更好的写法是
         public final class SingleTon {                  private volatile static SingleTon sInstance;                       public static SingleTon getInstance() {                            if (sInstance != null) {                                    return sInstance;                            }                            synchronized(SingleTon.class) {                           if (sInstance == null) {                                     sInstance = new SingleTon();                           }                            }                            return sInstance;                   }        }

        如果不使用锁, 能不能实现单例呢?  答案是可以的, 肯定要借助静态内部类了。        public final class SingleTon {
               private SingleTon() {
               }
               private static class Inner {
                      static SingleTon sInstance = new SingleTon ();  //私有静态类, 只会执行一次new
                }
                public static SingleTon getInstance() {
                       return Inner.sInstance;
                }
        }
         这种写法看起来很高大上, 没用到synchroized关键字实现了锁, 保证一个进程只有一个实例。
            
Swift3.0单例模式的2个写法如下, 虽然没有同步关键字, 但苹果已经说了加上static关键字后多线程时也能保证是一个实例。  
        注意要声明init函数, 而且是private访问类型, 从而只能通过类的静态参数得到实例。

苹果的说明:In Swift, you can simply use a static type property, which is guaranteed to be lazily initialized only once, even when accessed across multiple threads simultaneouslyfinal class SingleTon {
//单例类的属性
var name: String
var age: Int

private init() {
name = ""
age = 0
print("SingleTon init is called")
}

static let sInstance = SingleTon()
}

final class SingleTon2 {
//单例类的属性
var name: String
var age: Int

private init() {
name = ""
age = 0
print("SingleTon init is called")
}

//使用闭包的GET语法, 类似于lazy参数, 在运行时赋初值
static var sInstance: SingleTon2 {
let instance = SingleTon2()
instance.name = "zhangsan"
instance.age = 20

return instance
}
}

   在Swift语言中default是关键字, 如果想用default作为变量名, 可以转义。 PS: Swift的其它关键字也可以这样转义!!!
class SomeClass {
var param = 1

public static let `default` = SomeClass()
}

print(SomeClass.default.param) 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  单例