Swiftvariables是primefaces吗?

在Objective-C中,你可以区分primefaces和非primefaces属性:

@property (nonatomic, strong) NSObject *nonatomicObject; @property (atomic, strong) NSObject *atomicObject; 

从我的理解中,您可以安全地读取和写入从多个线程定义为primefaces的属性,同时从多个线程写入和访问非primefaces属性或ivars可能会导致未定义的行为,包括访问错误。

所以如果你在Swift中有这样一个variables:

 var object: NSObject 

我可以安全地并行读写这个variables吗? (不考虑这样做的实际意义)。

现在假设没有低级文档是很早的,但是你可以从汇编中学习。 料斗反汇编是一个伟大的工具。

 @interface ObjectiveCar : NSObject @property (nonatomic, strong) id engine; @property (atomic, strong) id driver; @end 

分别objc_setProperty_atomicprimefaces和primefaces使用objc_storeStrongobjc_setProperty_atomic ,其中

 class SwiftCar { var engine : AnyObject? init() { } } 

使用从libswift_stdlib_core ,显然,没有内置的线程安全。

我们可以推测其他关键字(类似于@lazy )可能稍后会被引入。

更新07/20/15 :根据这个关于单身 swift环境的博客可以使某些情况对你来说是安全的,即:

 class Car { static let sharedCar: Car = Car() // will be called inside of dispatch_once } private let sharedCar: Car2 = Car2() // same here class Car2 { } 

更新05/25/16 :留意快速进化的build议https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md – 它看起来像是将可能有自己实现的@atomic行为。

Swift没有围绕线程安全的语言结构。 假设您将使用提供的库来执行您自己的线程安全pipe理。 在实现线程安全方面有很多选项,包括pthread mutexes,NSLock和dispatch_sync作为互斥体机制。 请参阅Mike Ash最近关于这个主题的文章: https : //mikeash.com/pyblog/friday-qa-2015-02-06-locks-thread-safety-and-swift.html所以直接回答你的问题“Can我安全地并行读写这个variables?“ 没有。

回答这个问题可能会很早。 目前swift缺less访问修饰符,所以没有明显的方法来添加代码来pipe理属性getter / setter的并发性。 而且,Swift语言似乎还没有关于并发的任何信息! (它也缺乏KVO等…)

我认为这个问题的答案将在未来的版本中变得清晰。

细节

xCode 9.1,Swift 4

链接

  • apple.developer.com调度
  • Grand Central Dispatch(GCD)和Swift 3中的调度队列
  • 在Swift中创build线程安全的数组
  • Swift中的互斥锁和闭包

primefaces访问的示例

 class Atomic { let dispatchGroup = DispatchGroup() private var variable = 0 // Usage of semaphores func semaphoreSample() { // value: 1 - number of threads that have simultaneous access to the variable let atomicSemaphore = DispatchSemaphore(value: 1) variable = 0 runInSeveralQueues { dispatchQueue in // Only (value) queqes can run operations betwen atomicSemaphore.wait() and atomicSemaphore.signal() // Others queues await their turn atomicSemaphore.wait() // Lock access until atomicSemaphore.signal() self.variable += 1 print("\(dispatchQueue), value: \(self.variable)") atomicSemaphore.signal() // Unlock access } notifyWhenDone { atomicSemaphore.wait() // Lock access until atomicSemaphore.signal() print("variable = \(self.variable)") atomicSemaphore.signal() // Unlock access } } // Usage of sync of DispatchQueue func dispatchQueueSync() { let atomicQueue = DispatchQueue(label: "dispatchQueueSync") variable = 0 runInSeveralQueues { dispatchQueue in // Only queqe can run this closure (atomicQueue.sync {...}) // Others queues await their turn atomicQueue.sync { self.variable += 1 print("\(dispatchQueue), value: \(self.variable)") } } notifyWhenDone { atomicQueue.sync { print("variable = \(self.variable)") } } } // Usage of objc_sync_enter/objc_sync_exit func objcSync() { variable = 0 runInSeveralQueues { dispatchQueue in // Only one queqe can run operations betwen objc_sync_enter(self) and objc_sync_exit(self) // Others queues await their turn objc_sync_enter(self) // Lock access until objc_sync_exit(self). self.variable += 1 print("\(dispatchQueue), value: \(self.variable)") objc_sync_exit(self) // Unlock access } notifyWhenDone { objc_sync_enter(self) // Lock access until objc_sync_exit(self) print("variable = \(self.variable)") objc_sync_exit(self) // Unlock access } } } // Helpers extension Atomic { fileprivate func notifyWhenDone(closure: @escaping ()->()) { dispatchGroup.notify(queue: .global(qos: .utility)) { closure() print("All work done") } } fileprivate func runInSeveralQueues(closure: @escaping (DispatchQueue)->()) { async(dispatch: .main, closure: closure) async(dispatch: .global(qos: .userInitiated), closure: closure) async(dispatch: .global(qos: .utility), closure: closure) async(dispatch: .global(qos: .default), closure: closure) async(dispatch: .global(qos: .userInteractive), closure: closure) } private func async(dispatch: DispatchQueue, closure: @escaping (DispatchQueue)->()) { for _ in 0 ..< 100 { dispatchGroup.enter() dispatch.async { let usec = Int(arc4random()) % 100_000 usleep(useconds_t(usec)) closure(dispatch) self.dispatchGroup.leave() } } } } 

用法

 Atomic().semaphoreSample() //Atomic().dispatchQueueSync() //Atomic().objcSync() 

结果

在这里输入图像说明