ProgrammingSenior iOS Developer

How do static and class properties work in Swift, what pitfalls can arise from their usage, and how to implement thread-safe statics?

Pass interviews with Hintsage AI assistant

Answer.

Static and class properties are properties that belong to the type rather than the instance. Historically, they emerged to solve the problem of storing information that is common to all instances (e.g., counters, configurations, factories). In Swift, static can be used in all types (class, struct, enum), while class can only be used in classes and only for computed properties, allowing for overriding in subclasses.

Problem: Improper use of static properties can lead to race conditions and errors when accessed from different threads. It is also容易 confuse static and class and incorrectly choose the mechanism for overriding in subclasses.

Solution:

  • Use static for immutable or explicitly thread-safe properties.
  • For inheritance and overriding — define class property.
  • For thread safety — store data in a private static storage and access it only through synchronized logic (e.g., through DispatchQueue).

Example code:

class Counter { static var count = 0 static let queue = DispatchQueue(label: "counter.queue") static func increment() { queue.sync { count += 1 } } class var typeDescription: String { return "Generic Counter" } } class NamedCounter: Counter { override class var typeDescription: String { return "Named Counter" } }

Key features:

  • static cannot be overridden, class var can be.
  • static works for all types, class only for classes.
  • Static properties have one copy per type, accessible from anywhere in the code.

Trick questions.

Question 1: Can a static let property be declared as a computed property with get?

Yes, a static property can be either stored or computed. For let properties, it is usually a constant; however, a static var can certainly be computed:

struct Math { static var pi: Double { return 3.1415926 } }

Question 2: Are static vars thread-safe by default?

No, if a static var is modified from different threads, race conditions can occur. Read/write must be manually synchronized.

Question 3: Can class var be used for stored properties?

No, class var must always be a computed property (property with get/optional set), stored properties are allowed only for static.

Common mistakes and anti-patterns

  • Leaving static vars unsynchronized in a multithreaded environment.
  • Trying to declare a stored class var.
  • Confusing static and class, choosing the wrong mechanism for inheritance.

Real-life example

Negative case

In an application, a user login counter was stored in a static var and incremented from different threads without synchronization.

Pros:

  • Easy to implement.

Cons:

  • As a result, the counter sometimes gave incorrect values, complicating debugging and bug tracking.

Positive case

For a global configuration object, static let was used, and access to it was only for reading or using DispatchQueue for writing.

Pros:

  • Absence of races and predictable behavior.
  • Maintains thread safety.

Cons:

  • The code volume slightly increased due to queue wrapping.