0
0
Swiftprogramming~5 mins

Actors vs locks decision in Swift

Choose your learning style9 modes available
Introduction

Actors and locks help keep your program safe when many parts try to use the same data at once. Choosing between them helps avoid mistakes and crashes.

When you want to protect shared data from being changed by many parts at the same time.
When you need simple and safe ways to manage tasks running together.
When you want to avoid complex bugs caused by multiple parts accessing data simultaneously.
When you want your code to be easier to read and maintain.
When you want to use Swift's modern concurrency features for safety.
Syntax
Swift
actor MyActor {
    var count = 0

    func increment() {
        count += 1
    }
}

// Using a lock
class MyClass {
    private var count = 0
    private let lock = NSLock()

    func increment() {
        lock.lock()
        count += 1
        lock.unlock()
    }
}

Actors are special types that protect their data automatically.

Locks are manual tools you use to protect data by telling when to wait and when to go.

Examples
This actor safely changes its value without extra work.
Swift
actor Counter {
    var value = 0

    func increment() {
        value += 1
    }
}
This class uses a lock to make sure only one part changes value at a time.
Swift
class Counter {
    private var value = 0
    private let lock = NSLock()

    func increment() {
        lock.lock()
        value += 1
        lock.unlock()
    }
}
Sample Program

This program shows two ways to protect data: one with an actor and one with a lock. Both count up safely.

Swift
import Foundation

actor SafeCounter {
    var count = 0

    func increment() {
        count += 1
    }

    func getCount() -> Int {
        return count
    }
}

class LockedCounter {
    private var count = 0
    private let lock = NSLock()

    func increment() {
        lock.lock()
        count += 1
        lock.unlock()
    }

    func getCount() -> Int {
        lock.lock()
        let current = count
        lock.unlock()
        return current
    }
}

func testCounters() async {
    let safeCounter = SafeCounter()
    let lockedCounter = LockedCounter()

    // Increment both counters 5 times
    for _ in 1...5 {
        await safeCounter.increment()
        lockedCounter.increment()
    }

    let safeCount = await safeCounter.getCount()
    let lockedCount = lockedCounter.getCount()

    print("SafeCounter count: \(safeCount)")
    print("LockedCounter count: \(lockedCount)")
}

@main
struct Main {
    static func main() async {
        await testCounters()
    }
}
OutputSuccess
Important Notes

Actors handle safety automatically, so you write less code and avoid mistakes.

Locks require you to remember to lock and unlock, which can cause bugs if forgotten.

Actors work well with Swift's async/await, making concurrency easier.

Summary

Actors protect data automatically and are easier to use with Swift concurrency.

Locks give manual control but need careful handling to avoid errors.

Choose actors for safety and simplicity; use locks when you need fine control.