Flyweight
Flyweight shares immutable data among many small objects. Each object retains only its unique state while a shared value stores common appearance or behavior.
iOS problem and when to use it
A map can show thousands of store annotations. Duplicating the same icon name, tint, and category label in every marker wastes memory and makes style updates harder.
Original example: shared marker styles
import Foundation
final class MarkerStyle {
let symbolName: String
let tintName: String
init(symbolName: String, tintName: String) {
self.symbolName = symbolName
self.tintName = tintName
}
}
final class MarkerStyleCatalog {
private var styles: [String: MarkerStyle] = [:]
func style(for category: String) -> MarkerStyle {
if let existing = styles[category] { return existing }
let created = MarkerStyle(
symbolName: category == "Cafe" ? "cup.and.saucer" : "mappin",
tintName: category == "Cafe" ? "brown" : "blue"
)
styles[category] = created
return created
}
}
struct StoreMarker {
let latitude: Double
let longitude: Double
let storeID: String
let category: String
}
let catalog = MarkerStyleCatalog()
let marker = StoreMarker(latitude: 37.33, longitude: -122.03,
storeID: "store-1", category: "Cafe")
let style = catalog.style(for: marker.category)Coordinates and store IDs stay per marker; every marker in a category can reference the same immutable MarkerStyle instance. In a MapKit annotation view, translate symbolName and tintName into an image and color at rendering time.
Production decisions
Only share immutable style data. Cache rendered UIImage values separately if profiling shows image creation is expensive. The catalog above is a reference type with mutable storage; isolate it to one actor or protect it if multiple tasks access it. Measure memory before adding a flyweight layer, since Swift value types can already be compact.
Separate shared and unique state
StoreMarker contains location and store identity because those differ for each annotation. MarkerStyleCatalog maps a category to one immutable MarkerStyle object. The first lookup creates the style; later lookups return that same reference. That is the flyweight: many markers can share one style instead of each retaining a duplicate style object. The catalog key is part of correctness, so the same category must always mean the same style configuration during its lifetime.
From example to MapKit
When configuring a reused annotation view, look up the marker's style and set its symbol and tint. MapKit may reuse views, so always apply the entire style, including default values, rather than assuming previous state was cleared. If a theme changes from light to dark, either make styles theme-specific in the cache key or invalidate the catalog. Sharing style metadata is separate from caching rendered images, which may have its own memory cost.
Failure modes and verification
Test reference identity for repeated category lookups, distinct styles for different categories, and invalidation after theme changes. Do not share mutable style objects: changing one marker would then change every marker unexpectedly. For small marker counts, plain Swift structs may be efficient enough; profile memory before adding a catalog.