Daily iOS
Concurrency

Actor reentrancy

This image cache actor built with Swift Concurrency sometimes sends two network requests for the same key. The actor protects its state, so why does this happen?

actor ImageCache {
    private var cache: [URL: UIImage] = [:]
    func image(for url: URL) async throws -> UIImage {
        if let hit = cache[url] { return hit }
        let img = try await download(url)
        cache[url] = img
        return img
    }
}
How would an interviewer hear this answer? You'll see whether they'd move on, dig in, or say no, and which sentences would trip you up. Your score doesn't change.
See the short answer

An actor is reentrant: it accepts other calls at await points, so while the first call waits on download, a second call sees a cache miss and requests again. There's no data race, but a check-then-write with an await in between becomes a logical race.

Share a question