Swift 中 synchronized

Cocoa和Objective-C 中加锁的方式有很多,但是在日常开发中最常用的应该是@synchronized,这个关键字可以用来修饰一个变量,并为其自动加上和解除互斥锁。这样,可以保证变量在作用范围内不会被其他线程改变

@synchronized(self) {
//给 self 加锁
}

虽然这个方法很简单好用,但是很不幸的是在Swift 中它已经不存在了

那么在swift 中想要用这样的方式加锁,改怎么办呢?

其实@synchronized 在幕后做的事情是调用了objc_sync 中的objc_sync_enter 和objc_sync_exit 方法,并且加入了一些异常判断。因此,在Swift 中,如果我们忽略掉那些异常的话,我们想要lock 一个变量的话,可以这样写:

public func synchronized(_ lock: AnyObject, _ body: () throws -> T) rethrows -> T {
    objc_sync_enter(lock)
    defer { objc_sync_exit(lock) }
    return try body()
}

调用的时候这样调用就可以了:

synchronized(self) {
//... 代码
}

给对象加锁

public class Synchronized {
    /// Private value. Use `public` `value` computed property (or `reader` and `writer` methods)
    /// for safe, thread-safe access to this underlying value.
    
    private var _value: T
    
    /// Private reader-write synchronization queue
    
    private var queue: DispatchQueue
    
    /// Create `Synchronized` object
    ///
    /// - Parameter value: The initial value to be synchronized.
    ///             queueName: The initial queueName
    
    public init(_ value: T, queueName: String = "synchronized") {
        _value = value
        queue = DispatchQueue(label: Bundle.main.bundleIdentifier ?? "com.Synchronized" + "." +  queueName, qos: .default, attributes: .concurrent)
    }
    
    /// A threadsafe variable to set and get the underlying object
    
    public var value: T {
        get { return queue.sync { _value } }
        set { queue.async(flags: .barrier) { self._value = newValue } }
    }
    
    /// A "reader" method to allow thread-safe, read-only concurrent access to the underlying object.
    ///
    /// - Warning: If the underlying object is a reference type, you are responsible for making sure you
    ///            do not mutating anything. If you stick with value types (`struct` or primitive types),
    ///            this will be enforced for you.
    
    public func reader(_ block: (T) throws -> U) rethrows -> U {
        return try queue.sync { try block(_value) }
    }
    
    /// A "writer" method to allow thread-safe write with barrier to the underlying object
    
    public func writer(_ block: @escaping (inout T) -> Void) {
        queue.async(flags: .barrier) {
            block(&self._value)
        }
    }
}

你可能感兴趣的:(Swift 中 synchronized)