---
title: OSAllocatedUnfairLock
framework: os
role: symbol
role_heading: Structure
path: os/osallocatedunfairlock
---

# OSAllocatedUnfairLock

A structure that creates an unfair lock.

## Declaration

```swift
@frozen struct OSAllocatedUnfairLock<State>
```

## Overview

Overview Unfair locks are low-level locks that block efficiently on contention. They’re useful for protecting code that loads stored resources. However, it’s unsafe to use os_unfair_lock from Swift because it’s a value type and, therefore, doesn’t have a stable memory address. That means when you call os_unfair_lock_lock or os_unfair_lock_unlock and pass a lock object using the & operator, the system may lock or unlock the wrong object. Instead, use OSAllocatedUnfairLock, which avoids that pitfall because it doesn’t function as a value type, despite being a structure. All copied instances of an OSAllocatedUnfairLock control the same underlying lock allocation. important: If you’ve existing Swift code that uses os_unfair_lock, change it to use OSAllocatedUnfairLock to ensure correct locking behavior. To create a lock that protects operation state, create an enumeration that contains the possible states, then create a lock object, passing the initial state. Here’s an example of what that looks like for an asset load operation: enum MyState {     case idle     case loading     case complete(MyAsset)     case error(Error) } let protectedState = OSAllocatedUnfairLock(initialState: MyState.idle) Storing the state inside the lock helps track what the lock is protecting, and provides a way to safely access the state. To begin using the lock, call withLock(_:) or withLockIfAvailable(_:), passing a closure that contains the code for the lock to protect, like in the following example: func myLoadMethod() {     protectedState.withLock { state in         state = .loading     }     var (resource, error) = loadMyResources()     if resource != nil {         protectedState.withLock { state in             state = .complete(resource)         }     } else {         protectedState.withLock { state in             state = .error(error!)         }     } } To protect an operation with an externally defined state or no state, create a lock object without specifying an initial state. Nonscoped locking is more flexible, but offers no assistance in tracking the state of the operation the lock protects. To use a nonscoped lock, use withLock(_:) or withLockIfAvailable(_:). let myLock = OSAllocatedUnfairLock() myLock.withLock {     // Code that needs protection. } You can also use OSAllocatedUnfairLock with the more traditional lock/unlock approach by calling lock() before executing code that needs protection, and unlock() upon completion, like this: myLock.lock() // Code that needs protection. myLock.unlock() When using this approach, you must call unlock() from the same thread you use to call lock(). Because of this, it’s unsafe to use this approach across an await suspension point. When using a lock with asynchronous code, lock using a closure or, even better, consider using an Actor. warning: OSAllocatedUnfairLock isn’t a recursive lock. Attempting to lock an object more than once from the same thread without unlocking in between triggers a runtime exception.

## Topics

### Creating a lock object

- [init()](os/osallocatedunfairlock/init().md)
- [init(initialState:)](os/osallocatedunfairlock/init(initialstate:).md)

### Using locks

- [lock()](os/osallocatedunfairlock/lock().md)
- [lockIfAvailable()](os/osallocatedunfairlock/lockifavailable().md)
- [unlock()](os/osallocatedunfairlock/unlock().md)

### Determining lock ownership

- [OSAllocatedUnfairLock.Ownership](os/osallocatedunfairlock/ownership.md)
- [precondition(_:)](os/osallocatedunfairlock/precondition(_:).md)

### Initializers

- [init(uncheckedState:)](os/osallocatedunfairlock/init(uncheckedstate:).md)

### Instance Methods

- [lock(flags:)](os/osallocatedunfairlock/lock(flags:).md)
- [withLock(_:)](os/osallocatedunfairlock/withlock(_:)-1uy7m.md)
- [withLock(_:)](os/osallocatedunfairlock/withlock(_:)-hple.md)
- [withLock(flags:_:)](os/osallocatedunfairlock/withlock(flags:_:)-1ub4c.md)
- [withLock(flags:_:)](os/osallocatedunfairlock/withlock(flags:_:)-u2xj.md)
- [withLockIfAvailable(_:)](os/osallocatedunfairlock/withlockifavailable(_:)-1rp3w.md)
- [withLockIfAvailable(_:)](os/osallocatedunfairlock/withlockifavailable(_:)-3kw0o.md)
- [withLockIfAvailableUnchecked(_:)](os/osallocatedunfairlock/withlockifavailableunchecked(_:)-15q0y.md)
- [withLockIfAvailableUnchecked(_:)](os/osallocatedunfairlock/withlockifavailableunchecked(_:)-6gji7.md)
- [withLockUnchecked(_:)](os/osallocatedunfairlock/withlockunchecked(_:)-7qywq.md)
- [withLockUnchecked(_:)](os/osallocatedunfairlock/withlockunchecked(_:)-9v03m.md)
- [withLockUnchecked(flags:_:)](os/osallocatedunfairlock/withlockunchecked(flags:_:)-8cv64.md)
- [withLockUnchecked(flags:_:)](os/osallocatedunfairlock/withlockunchecked(flags:_:)-9iq8s.md)

## Relationships

### Conforms To

- [Sendable](swift/sendable.md)
- [SendableMetatype](swift/sendablemetatype.md)

## See Also

### Swift Wrappers

- [OSAllocatedUnfairLockFlags](os/osallocatedunfairlockflags.md)
