@Syncthronized on Swift
前言
王巍大神的《swifter-tips》里面有一节介绍:LOCK
文章中介绍了在日常开发中最常用的 @synchronized
锁,在Swift中移除了,并给出了一个简单的替代实现:
func synchronized(_ lock: AnyObject, closure: ()->()) {
objc_sync_enter(lock)
closure()
objc_sync_exit(lock)
}
func lock(obj: AnyObject) {
synchronized(obj) {
/// 这里obj不会被其他线程改变
}
}
正文:
上面的实现方法如此简单,让我有点疑惑,于是我谷歌了一些相关的资料,在这里做一下补充。
首先,在stackoverflow上有人也给出过相似的答案,但是笔者自己也指出了这个实现方式存在问题:
There is one problem I've found with this. Passing in an array as the lock argument seems to cause a very obtuse compiler error at this point. Otherwise though it seems to work as desired.
字面意思大概是在加锁对象是数组的时候,会出现一个编译错误
然后,有人对这种实现方式给出了改进:defer
func synchronized(_ lock: AnyObject, closure: ()->()) {
objc_sync_enter(lock)
defer { objc_sync_exit(lock) }
closure()
}
defer
关键字的作用在于:在作用域结束时执行,将defer代码块中的代码做出栈操作
最后,给大家提供另外一种思路,用一个 串行同步队列
代替:
let queue = dispatch_queue_create("com.test.LockQueue", nil)
dispatch_sync(queue) {
// code
}
这里只是给提供一些实现方式供大家参考。
同时,也分享一个用NSLocking
封装的解决方案:locking.swift
结语:
讲讲为什么写这篇分享文章吧:
今天看到一个关于Swift性能优化
的文章时,提到了对结构体进行内存再分配时会耗费大量时间,其中涉及到了面向协议编程,也展示了协议会导致性能下降,于是那篇文章给出了一个解决方案:泛型
。这下就更懵逼了,于是就是了解泛型,最后看到了王巍大神的《swifter-tips》中的 泛型扩展
,一路到最后也没搞清楚,却看到了开头提到的 LOCK,所以之后可能会研究一下协议和结构体的东西,当然还有泛型。
参考:
What is the Swift equivalent to Objective-C's “@synchronized”?
defer, Defer