2017-08-08 41 views
1
public class Account { 
    // MARK: Initializer 
    // Custom initializer 

    // MARK: Stored Properties 
    let concurrentQueue: DispatchQueue = DispatchQueue(
     label: "concurrentQueue", 
     qos: DispatchQoS.userInitiated, 
     attributes: [DispatchQueue.Attributes.concurrent] 
    ) 

    private var _name: String 

    public name: String { 
     get { 
      return self.concurrentQueue.sync { return self._name } 
     } 

     set { 
      self.concurrentQueue.async(flags: .barrier) { 
       self._name = newValue 
      } 
     } 
    } 
} 

假設你有一個像上面那樣想要線程安全的類。在Swift中創建線程安全讀取時,爲什麼在併發隊列外創建一個變量?

Account這個類的getter與定義這樣的getter有什麼區別?

get { 
    var result: String! 
    self.concurrentQueue.sync { result = self._name } 
    return result 
}  

我目前正在圍繞線程安全進行包裝,並且總是看到像後者一樣創建的讀取。在我看來,他們幾乎是一樣的...我錯了嗎?

來源:GCD Tutorial

+0

後者僅僅是實現前者更令人費解的版本 – Alexander

回答

1

沒有區別。有兩種方法DispatchQueue.sync

public func sync(execute block:() -> Swift.Void) 
public func sync<T>(execute work:() throws -> T) rethrows -> T 

,並在你的第一個例子中,第二個用於:封閉可以返回一個值,然後成爲sync調用的返回值 。因此,在

get { 
    return self.concurrentQueue.sync { return self._name } 
} 

sync { ... }返回值是self._name和從吸氣方法返回 。這相當於(但比簡單)存儲在臨時變量的 值(這裏的封閉返回Void):

get { 
    var result: String! 
    self.concurrentQueue.sync { result = self._name } 
    return result 
} 

當然,只有擁有同步出動封鎖,並不適用於異步調用 。這些被存儲以後執行,並且必須 返回Void

public func async(..., execute work: @escaping @convention(block)() -> Swift.Void) 
相關問題