Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Build Status Issues Status License
Contact Sponsor


Concurrency made simple in Swift.

AtomicKit is a Swift framework designed to ease dealing with concurrency in Swift projects.


Coming from Objective-C and C++, I lacked a few features in Swift, like Objective-C's @atomic or C++'s std::atomic.

Apple's GCD (Grand Central Dispatch) is absolutely awesome when it comes to synchronization, but you'll have to use it explicitely in Swift.
Writing atomic/dispatched getters and setters is not a big deal, but it currently leads to a lot of boilerplate code, which I like to avoid in my projects.

The AtomicKit project intends to simplify this, by adding easy-to-use synchronization Swift types.


Documentation and API reference can be found at:

Synchronization Primitives

AtomicKit exposes a few synchronization primitive types, like:

  • Mutex
  • RecursiveMutex
  • UnfairLock

These types conforms to the AtomicKit.Lockable protocol, which extends NSLocking, meaning they all have the following methods:

public func lock()
public func unlock()
public func tryLock() -> Bool


This is a wrapper for pthread_mutex_t.
This version is not recursive.


This is a wrapper for pthread_mutex_t.
This version is recursive.


This is a wrapper for os_unfair_lock_t.


AtomicKit provides a Semaphore class.
Semaphores are initialized with a count, and may be named, in which case they are shared between multiple processes.

The Semaphore class exposes the following methods:

public init( count: Int32 = 1, name: String? = nil )
public func wait()
public func signal()
public func tryWait() -> Bool

Internally, the Semaphore class uses POSIX semaphores for named semaphores, and MACH semaphores for unnamed semaphores.

Read-Write Locks

AtomicKit supports read-write locking mechanism using the RWLock class:

public enum Intent
    case reading
    case writing

public func lock( for intent: Intent )
public func unlock()
public func tryLock( for intent: Intent ) -> Bool

Atomic Properties

AtomicKit provides a generic type called Atomic.
If you're familiar with C++, you can think of it as std::atomic.

The goal is to provide a thread-safe property type that you can use in your own classes:

class Foo
    public var bar = Atomic< Bool >( value: false )

The example above declares an atomic Boolean property.

Its value can be get with:

And can be set with: true )

Internally, Atomic uses an UnfairLock.

If more complex stuff is required with the value it holds, the Atomic generic type lets you execute a custom closure.

let foo = Atomic< String >( value: "hello" )

foo.execute{ ( value: String ) in value.append( ", world" ) }

You can also use a return value from the closure:

let isEmpty = foo.execute{ ( value: String ) -> Bool in value.isEmpty }

Atomicity is guaranteed in both cases.


Under the hood, the Atomic class inherits from LockingValue.
LockingValue works just the same, but takes an extra generic parameter specifying the type of lock used for synchronization.

As mentioned above, Atomic uses an UnfairLock.
Using LockingValue, you can specify another type of locking mechanism, as long as it conforms to the NSLocking protocol:

let foo = LockingValue< String?, NSRecursiveLock >( value: nil )

Dispatched Atomic Properties

Using a locking mechanism is a way to achieve synchronization.
But using dispatch queues also ensure synchronization between multiple concurrent accesses.

AtomicKit supports this through the DispatchedValue generic class.

A DispatchedValue is initialized with a default value, and with a dispatch queue:

let foo = DispatchedValue< String >( value: "", queue: DispatchQueue.main )

Then, every call to the get or set methods will be executed on the provided queue, thus achieving effective synchronization.

As the Atomic type, DispatchedValue also lets you execute custom closures, that will be executed on the provided queue:

let foo = DispatchedValue< String >( value: "hello", queue: DispatchQueue.main )

foo.execute{ ( value: String ) in value.append( ", world" ) }

let isEmpty = foo.execute{ ( value: String ) -> Bool in value.isEmpty }

Dispatched properties and KVO

As it's a Swift generic type, the DispatchedValue class cannot be used from Objective-C, and so can't be used with KVO (key-value observing).

This might be a problem, especially if your project relies on Cocoa bindings, which use KVO.

AtomicKit solves this by exposing Objective-C and KVO compatible versions of DispatchedValue, specialized for common Objective-C types:

  • DispatchedArrayController
  • DispatchedBool
  • DispatchedMutableArray
  • DispatchedMutableDictionary
  • DispatchedMutableSet
  • DispatchedNumber
  • DispatchedObject
  • DispatchedString
  • DispatchedTree

All of these types defaults to the main dispatch queue, if none is provided.
This is especially handy when using Cocoa bindings, as changes often needs to occur on the main thread, for UI reasons.

All of these specializations expose a value property, which is observable using KVO.
It also means you can safely use Cocoa bindings with them.


AtomicKit is released under the terms of the MIT license.

Repository Infos

Owner:          Jean-David Gadina - XS-Labs
Twitter:        @macmade