Swift中如何安全的创建一个单例

13 篇文章 0 订阅

Talk is cheap. Show me the code.


class TestShareInstance{
    var age:Int
    static let shareInstane:TestShareInstance = TestShareInstance(age: 3);
    private init(age:Int){
        self.age = age;
    };
}
 


说说原理

1. swift在类中,类变量是能够保证线程安全,swift底层,static关键字的实际上是使用`dispatch_once`语法来实现的,如下一段swift编译中间产物SIL语言中的代码就能看到底层的实现.staic变量被声明为全局变量


// static TestShareInstance.shareInstane
sil_global hidden [let] @static main.TestShareInstance.shareInstane : main.TestShareInstance : $TestShareInstance
 


2.在get方法中获取变量调用了swift内嵌的builtin "once",实际上调用的是`swift_once`方法

sil单例


3.在swift源码中可以搜索到`swift_once`方法的内部实现如下,内部调用的就是GCD底层的`dispatch_once_f`,保证了单例的线程安全。


```
/// Runs the given function with the given context argument exactly once.
/// The predicate argument must point to a global or static variable of static
/// extent of type swift_once_t.
void swift::swift_once(swift_once_t *predicate, void (*fn)(void *),
                       void *context) {
#if defined(__APPLE__)
  dispatch_once_f(predicate, context, fn);
#elif defined(__CYGWIN__)
  _swift_once_f(predicate, context, fn);
#else
  std::call_once(*predicate, [fn, context]() { fn(context); });
#endif
}
```


在类中,将TestShareInstance的init方法设置为了private属性,这能保证其他人没有办法调用你的init的方法,只能调用你的shareInstane单例变量;从而保证了单例的不可修改特性。如果你要强行修改,编译器就会警告你,具体示例如下

swiftonce

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值