swift中闭包函数的运用

今天分析了一下Alamofire源码,其中看到了lock的使用场景,那么Alamofire作者很巧妙的运用了swift的闭包解决了锁的使用复杂度。

首先定义了一个class UnfairLock锁类型,封装了对os_unfair_lock_t的操作,看代码:

 1 final class UnfairLock {
 2     private let unfairLock: os_unfair_lock_t
 3 
 4     init() {
 5         unfairLock = .allocate(capacity: 1)
 6         unfairLock.initialize(to: os_unfair_lock())
 7     }
 8 
 9     deinit {
10         unfairLock.deinitialize(count: 1)
11         unfairLock.deallocate()
12     }
13 
14     private func lock() {
15         os_unfair_lock_lock(unfairLock)
16     }
17 
18     private func unlock() {
19         os_unfair_lock_unlock(unfairLock)
20     }
21 }

UnfairLock是一个final类型的类,这代表它不能被继承,也就是一个最终的类。在init初始化方法中,初始了os_unfair_lock_t锁,因为它是UnsafeMutablePointer<os_unfair_lock_s>类型的别名,所以在初始化的时候,需要采用UnsafeMutablePointer.allocate(capacity count: Int)开辟指针的内存空间,然后通过initialize(to value: Pointee) 初始化指针对象,更多关于指针的操作可以查看这篇文章《Swift 中的指针使用》

在deinit中对锁指针进行垃圾回收(swift中关于指针的操作,都需要手动管理内存)

作者定义了两个私有函数,分别对应锁的上锁和解锁两个操作,用于类内部使用。

1 func around<T>(_ closure: () -> T) -> T {
2         lock(); defer { unlock() }
3         return closure()
4   }
5 
6 func around(_ closure: () -> Void) {
7         lock(); defer { unlock() }
8         return closure()
9  }

以上两个函数,就是利用swift的闭包加上defer{}的运用,巧妙的封装的锁的加锁和解锁,Swift 里的 defer 大家应该都很熟悉了,defer 所声明的 block 会在当前代码执行退出后被调用。正因为它提供了一种延时调用的方式,所以一般会被用来做资源释放或者销毁,这在某个函数有多个返回出口的时候特别有用。关于defer操作可以参考《关于 Swift defer 的正确使用》这篇文章。

在使用方面如下:在使用该锁的类型中初始化该锁对象,然后在需要上锁的操作中这样调用

 1 final class Protector<T> {
 2     private let lock = UnfairLock()
 3     private var value: T
 4 
 5     init(_ value: T) {
 6         self.value = value
 7     }
 8 
 9     /// The contained value. Unsafe for anything more than direct read or write.
10     var directValue: T {
11         get { return lock.around { value } }
12         set { lock.around { value = newValue } }
13     }
14 }
调用返回值的锁:lock.around { value }
调用不带返回值的锁:lock.around { value = newValue }

 

posted @ 2019-11-11 15:16  zbblogs  阅读(735)  评论(0)    收藏  举报