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:
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:
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.
In an application, a user login counter was stored in a static var and incremented from different threads without synchronization.
Pros:
Cons:
For a global configuration object, static let was used, and access to it was only for reading or using DispatchQueue for writing.
Pros:
Cons: