Swift 中 synchronized

Cocoa和Objective-C 中加鎖的方式有很多,但是在日常開發(fā)中最常用的應(yīng)該是@synchronized,這個(gè)關(guān)鍵字可以用來修飾一個(gè)變量,并為其自動加上和解除互斥鎖。這樣,可以保證變量在作用范圍內(nèi)不會被其他線程改變

@synchronized(self) {
//給 self 加鎖
}

雖然這個(gè)方法很簡單好用,但是很不幸的是在Swift 中它已經(jīng)不存在了

那么在swift 中想要用這樣的方式加鎖,改怎么辦呢?

其實(shí)@synchronized 在幕后做的事情是調(diào)用了objc_sync 中的objc_sync_enter 和objc_sync_exit 方法,并且加入了一些異常判斷。因此,在Swift 中,如果我們忽略掉那些異常的話,我們想要lock 一個(gè)變量的話,可以這樣寫:

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

調(diào)用的時(shí)候這樣調(diào)用就可以了:

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

給對象加鎖

public class Synchronized<T> {
    /// 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<U>(_ 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)
        }
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容