Sunday, June 14, 2026
HomeiOS DevelopmentSwift object pool design sample

Swift object pool design sample

[ad_1]

A generic object pool in Swift

The object pool sample is a creational design sample. The principle concept behind it’s that first you create a set of objects (a pool), then you definately purchase & launch objects from the pool, as a substitute of continually creating and releasing them. 👍

Why? Efficiency enhancements. For instance the Dispatch framework makes use of an object pool sample to provide pre-created queues for the builders, as a result of making a queue (with an related thread) is an comparatively costly operation.

One other use case of the object pool sample is employees. For instance you need to obtain tons of of photos from the online, however you’d wish to obtain solely 5 concurrently you are able to do it with a pool of 5 employee objects. In all probability it will be loads cheaper to allocate a small variety of employees (that’ll truly do the obtain activity), than create a brand new one for each single picture obtain request. 🖼

What in regards to the downsides of this sample? There are some. For instance when you have employees in your pool, they could comprise states or delicate consumer knowledge. You need to be very cautious with them aka. reset every part. Additionally if you’re operating in a multi-threaded setting you need to make your pool thread-safe.

Right here is an easy generic thread-safe object pool class:

import Basis

class Pool<T> {

    personal let lockQueue = DispatchQueue(label: "pool.lock.queue")
    personal let semaphore: DispatchSemaphore
    personal var objects = [T]()

    init(_ objects: [T]) {
        self.semaphore = DispatchSemaphore(worth: objects.rely)
        self.objects.reserveCapacity(objects.rely)
        self.objects.append(contentsOf: objects)
    }

    func purchase() -> T? {
        if self.semaphore.wait(timeout: .distantFuture) == .success, !self.objects.isEmpty {
            return self.lockQueue.sync {
                return self.objects.take away(at: 0)
            }
        }
        return nil
    }

    func launch(_ merchandise: T) {
        self.lockQueue.sync {
            self.objects.append(merchandise)
            self.semaphore.sign()
        }
    }
}


let pool = Pool<String>(["a", "b", "c"])

let a = pool.purchase()
print("(a ?? "n/a") acquired")
let b = pool.purchase()
print("(b ?? "n/a") acquired")
let c = pool.purchase()
print("(c ?? "n/a") acquired")

DispatchQueue.world(qos: .default).asyncAfter(deadline: .now() + .seconds(2)) {
    if let merchandise = b {
        pool.launch(merchandise)
    }
}

print("No extra useful resource within the pool, blocking thread till...")
let x = pool.purchase()
print("(x ?? "n/a") acquired once more")

As you may see the implementation is just some traces. You have got the thread protected array of the generic pool objects, a dispatch semaphore that’ll block if there aren’t any objects obtainable within the pool, and two strategies so as to truly use the item pool.

Within the pattern you may see that if there aren’t any extra objects left within the pool, the present queue can be blocked till a useful resource is being freed & prepared to make use of. So be careful & do not block the primary thread unintentionally! 😉

[ad_2]

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments