Search code examples
swiftswift3booleanios10atomicboolean

Swift 3 - Atomic boolean


Does anybody know how to make an atomic boolean in iOS 10?

Current code:

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

The code works as expected, but i keep getting the warning:

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

I can't get it to work with atomic_fetch_or_explicit(memory_order_relaxed).

Does anyone know how to convert my current code to iOS 10, in order to get rid of this warning?

Thank you!


Solution

  • the better way is to avoid it ... If you would like to mimick it just to synchronise access to your AtomicBoolean, use synchronisation avaiable in GCD

    for example

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

    prints

    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