Swift 原子布尔值

Swift atomic boolean

我正在尝试围绕 iOS OSTestAndSet()OSTestAndClear() 函数创建一个包装器,以便与基于以下 GitHub code 的原子布尔类型一起使用:

class AtomicBoolean {

    private var val: Byte = 0

    /// Sets the value, and returns the previous value.
    /// The test/set is an atomic operation.
    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
    }

}

但是,我收到 属性 声明的编译器错误:Use of undeclared type 'Byte'; did you mean to use 'UInt8'?

目前,我正在为此代码文件导入 Foundation。我已经看到其他 Whosebug 帖子使用 Byte 类型,但我无法找到为什么这在我的案例中不可用。

我正在使用 Swift 的以下版本: Apple Swift 版本 1.2 (swiftlang-602.0.53.1 clang-602.0.53)

此外,如果我按照编译器的建议将数据类型更改为 UInt8,我会在 OSAtomicTestAndSet() 和 OSAtomicTestAndClear() 调用中收到其他错误,这些错误说明如下:Cannot assign to immutable value of type 'UInt8' 尽管我是使用 var 声明而不是 let.

Xcode 7 Beta 4,Swift 2.0,对以下内容感到满意,这几乎是您使用 "UInt8" 与 "Byte" 的代码:

class AtomicBoolean {

    private var val: UInt8 = 0

    func testAndSet(value: Bool) -> Bool {
        if value {
            return OSAtomicTestAndSet(0, &val)
        } else {
            return OSAtomicTestAndClear(0, &val)
        }
    }

    func test() -> Bool {
        return val != 0
    }
}

ByteUInt8typealias 已删除,在 Swift 1.2 中不再存在。您可以自己定义它,或者只使用 UInt8(更好的选择)。

在评论中,您说不可变的问题是您使用的是 struct 而不是 class。您可以使用 struct,您只需将关键字 mutating 添加到任何修改 struct:

的函数
typealias Byte = UInt8

struct AtomicBoolean {

    private var val: Byte = 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
    }

}

请注意,此 class 的实现是伪造的。它设置最高有效位#0,而不是最低有效位#7。这是正确的实现:

public class AtomicBoolean {  
  private var val: UInt8 = 0

  public init(initialValue: Bool) {
    self.val = (initialValue == false ? 0 : 1)
  }

  public func getAndSet(value: Bool) -> Bool {
    if value {
      return  OSAtomicTestAndSet(7, &val)
    } else {
      return  OSAtomicTestAndClear(7, &val)
    }
  }

  public func get() -> Bool {
    return val != 0
  }
}

还有一个测试来验证:

public class AtomicTest: XCTestCase {

  func testSimple() {
    let x = AtomicBoolean(initialValue: true)
    XCTAssertTrue(x.get())
    XCTAssertTrue(x.get())
    XCTAssertTrue(x.getAndSet(true))
    XCTAssertTrue(x.getAndSet(false))
    XCTAssertFalse(x.get())
    XCTAssertFalse(x.getAndSet(true))
    XCTAssertTrue(x.get())
  }
}