LoginSignup
13
14

More than 5 years have passed since last update.

Swiftでのthread-safeなデータ操作

Last updated at Posted at 2015-12-26

atomic

最近Swiftでもっぱら書くことが多くなり
AtomicReference的なライブラリが欲しく作成してみました。

Lock.swift
class locker {
    private var l = NSRecursiveLock()

    func lock() -> Bool {
        self.l.lock()
        return true
    }

    func unlock() {
        self.l.unlock()
    }

    func safeCall<R>(f: () -> R) -> R {
        var r: R
        self.lock()
        r = f()
        self.unlock()
        return r
    }
}

Atomic.swift
// lockerを継承して、safeCallで安全に値を扱う。
class AtomicValue <T> : locker {
    private var value: T?

    init(v: T?) {
        self.value = v
    }

    func setV(v: T?) {
        self.safeCall(
            {() in
                self.value = v
            }
        )
    }

    func setV(f: (T?) -> T?) {
        self.safeCall(
            {() in
                self.value = f(self.value)
            }
        )
    }

    func getV() -> T? {
        return self.safeCall(
            {() -> T? in
                return self.value
            }
        )
    }

    func getV_and_SetV(v: T?) -> T? {
        return self.safeCall(
            {() -> T? in
                let r = self.value
                self.value = v
                return r
            }
        )
    }
}

使い方

Sample.swift
private var value = AtomicValue <Int> (v: 0)
private var counter: Int {
    get {
        return value.getV()!
    }

    set {
        value.setV(
            {(v: Int?) -> Int? in
                if let vv = v {
                    return vv + 1
                }
                return 0
            }
        )
    }
}

safeCallの中でlockをすると、dead lockになってしまうので
NSRecursiveLockを使っています。

しかし、Swiftは中々慣れない(。。

13
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14