When creating thread safe reads in Swift, why is a variable create outside the concurrent queue?

痞子三分冷 提交于 2019-12-08 08:04:14

问题


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
            }
        }
    }
}

Let's say you have a class like above where you want thread safety.

What is the difference between the getter in the Account class and defining the getter like this?

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

I'm currently wrapping my head around thread safety and I always see reads created like the latter. It seems to me they're virtually the same... am I wrong?

Source: GCD Tutorial


回答1:


There is no difference. There are two DispatchQueue.sync methods:

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

and in your first example the second one is used: The closure can return a value, which then becomes the return value of the sync call. Therefore in

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

the return value of sync { ... } is self._name and that is returned from the getter method. This is equivalent to (but simpler than) storing the value in a temporary variable (and here the closure returns Void):

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

Of course that works only with synchronously dispatched closures, not with asynchronous calls. These are stored for later execution and must return Void:

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


来源:https://stackoverflow.com/questions/45569118/when-creating-thread-safe-reads-in-swift-why-is-a-variable-create-outside-the-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!