【问题标题】:Swift 3 - Atomic booleanSwift 3 - 原子布尔值
【发布时间】:2017-11-24 21:31:51
【问题描述】:

有人知道如何在 iOS 10 中制作原子布尔值吗?

当前代码:

import UIKit

struct AtomicBoolean {
    fileprivate var val: UInt8 = 0

    /// Sets the value, and returns the previous value.
    /// The test/set is an atomic operation.
    mutating func testAndSet(_ value: Bool) -> Bool {
       if value {
           return OSAtomicTestAndSet(0, &val)
       } else {
           return OSAtomicTestAndClear(0, &val)
       }
    }

    /// Returns the current value of the boolean.
    /// The value may change before this method returns.
    func test() -> Bool {
      return val != 0
    }
}

代码按预期工作,但我不断收到警告:

'OSAtomicTestAndSet' was deprecated in iOS 10.0: Use atomic_fetch_or_explicit(memory_order_relaxed) from <stdatomic.h> instead

我无法让它与 atomic_fetch_or_explicit(memory_order_relaxed) 一起使用。

有谁知道如何将我当前的代码转换为 iOS 10,以消除此警告?

谢谢!

【问题讨论】:

  • 问题的重点大概应该是如何让atomic_fetch_or_explicit工作。不过,要做到这一点,您需要展示您使用它的尝试,并说明失败的原因。
  • 比较stackoverflow.com/questions/39356873/…。 – 编译器警告不推荐使用的 OSAtomic 函数,但不会从 &lt;stdatomic.h&gt; 导入函数。

标签: swift swift3 boolean ios10 atomicboolean


【解决方案1】:

你的第一个选择是……

  1. 只需使用普通锁并保护您的价值访问,另一个是...
  2. 使用Swift Atomics

那你就直接说

var value = ManagedAtomic<UInt8>(0)

// Atomic store
value.store(2, ordering: .relaxed)

// Atomic load
value.load(ordering: .relaxed)

【讨论】:

    【解决方案2】:

    Apple 确认 Bool 值的读写在 Swift 中不是原子操作。

    但是有很多方法可以同步。

    示例

    在下面添加全局函数逻辑:

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

    并像这样使用:

    let myLock = NSObject();
    
    // ...
    
    synchronized(myLock) {
        // Something not thread safe here...
    }
    

    【讨论】:

      【解决方案3】:

      更好的方法是避免它...如果您想模仿它只是为了同步对 AtomicBoolean 的访问,请使用 GCD 中可用的同步

      例如

      import PlaygroundSupport
      import Foundation
      import Dispatch
      
      PlaygroundPage.current.needsIndefiniteExecution = true
      
      let q = DispatchQueue(label: "print")
      
      struct AtomicBoolean {
          private var semaphore = DispatchSemaphore(value: 1)
          private var b: Bool = false
          var val: Bool  {
              get {
                  q.async {
                      print("try get")
                  }
                  semaphore.wait()
                  let tmp = b
                  q.async {
                      print("got", tmp)
                  }
                  semaphore.signal()
                  return tmp
              }
              set {
                  q.async {
                      print("try set", newValue)
                  }
                  semaphore.wait()
                  b = newValue
                  q.async {
                      print("did", newValue)
                  }
                  semaphore.signal()
              }
          }
      
      }
      var b = AtomicBoolean()
      
      DispatchQueue.concurrentPerform(iterations: 10) { (i) in
          if (i % 4 == 0) {
              _ = b.val
          }
          b.val = (i % 3 == 0)
      }
      

      打印

      try get
      try set false
      try set false
      try set true
      did false
      got false
      try get
      try set true
      did false
      try set false
      did true
      did true
      try set true
      try set false
      got false
      try set false
      did false
      try get
      did true
      try set true
      did false
      did false
      got false
      try set false
      did true
      did false
      

      【讨论】:

        猜你喜欢
        • 2017-04-08
        • 1970-01-01
        • 2017-03-27
        • 1970-01-01
        • 2021-12-27
        • 2017-09-27
        • 2021-05-21
        • 1970-01-01
        • 2013-02-09
        相关资源
        最近更新 更多