Skip to content

Object Pool ​

Object Pool reuses expensive objects instead of allocating and discarding them for every operation. iOS already pools some resources, such as reusable table and collection cells; build your own pool only after measuring a real cost.

When it helps in iOS ​

An image editor repeatedly creates a costly filter pipeline. A small pool can reuse prepared workers while avoiding unbounded memory growth.

Original example: bounded reusable workers ​

swift
import Foundation

final class FilterWorker {
    var intensity = 1.0

    func reset() { intensity = 1.0 }
}

final class FilterWorkerPool {
    private var available: [FilterWorker] = []
    private let maxIdleCount: Int

    init(maxIdleCount: Int = 2) { self.maxIdleCount = maxIdleCount }

    func acquire() -> FilterWorker {
        available.popLast() ?? FilterWorker()
    }

    func release(_ worker: FilterWorker) {
        worker.reset()
        if available.count < maxIdleCount { available.append(worker) }
    }
}

let pool = FilterWorkerPool()
let worker = pool.acquire()
worker.intensity = 0.6
pool.release(worker)

The caller acquires a worker and returns it after use; reset() prevents settings from leaking into the next edit.

Production decisions ​

Use defer at the call site to guarantee release when processing throws. Confine this simple pool to one actor or queue; it is not thread-safe. Never pool objects tied to a view lifecycle or user identity without careful cleanup. Respond to memory pressure by dropping idle workers. Compare against the cost of creating new objects before adding this complexity.

Follow the resource lifecycle ​

FilterWorkerPool holds idle workers only. acquire() removes one or constructs a new worker if none are idle. After processing, release(_:) calls reset() and retains the worker only if the idle count is below a bound. The bound limits idle memory, not the number of simultaneously acquired workers. This is suitable only if constructing a FilterWorker is significantly more expensive than resetting one.

From example to an image editor ​

A processing service acquires a worker, configures intensity, applies the filter, and releases it with defer so errors do not leak the worker. Keep the pool within one actor or queue because the sample storage is not synchronized. Image-editing objects may hold textures or pixel buffers; reset must clear all user-specific data, not just intensity. Respond to memory warnings by dropping idle workers if your pool retains large resources.

Failure modes and verification ​

Test reuse, reset, maximum idle count, and release after failure. Prevent the same worker from being released twice or used concurrently; a production pool may track checked-out identities. Measure allocation and processing times before and after pooling. UIKit's cell reuse is already a pool-like mechanism; do not add a second pool around table cells.

All patterns

Released under the MIT License.