Swift原子布尔值

时间:2015-08-12 01:18:54

标签: swift thread-safety

我正在尝试围绕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。我已经看到其他stackoverflow帖子使用字节类型,但我无法找到为什么这在我的情况下不可用。

我正在使用以下版本的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

3 个答案:

答案 0 :(得分:1)

typealiasByte的{​​{1}}已被删除,并且在Swift 1.2中不再存在。您可以自己定义它,或者只使用UInt8(更好的选项)。

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

struct

答案 1 :(得分:1)

请注意,这个课程的实施是很糟糕的。它设置最重要的位#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())
  }
}

答案 2 :(得分:0)

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