Skip to content

👩🏻‍💻 🧑🏽‍💻 Subscribe and Read us on Substack to Get Full Access to Our Posts


Structs vs. Classes in SwiftUI: When to Use Each and why we use Classes in SwiftData

In SwiftUI development, a common question arises: Should you use structs or classes for your models? While Swift is optimized for value types (structs), there are certain scenarios where using reference types (classes) becomes necessary, particularly when you work with data persistence frameworks like SwiftData.

This article will break down the key differences between structs and classes in modern SwiftUI development and how SwiftData influences these choices.

The Basics: Structs vs. Classes

Structs

  • Value types: Structs are copied when passed or assigned to new variables.
  • Immutable by default: Changes to a struct instance do not affect other copies.
  • No ARC (Automatic Reference Counting): Structs are more lightweight, and Swift can optimize them for better performance.
  • Better for simple data: Ideal for models that represent small, self-contained pieces of data.

Classes

  • Reference types: Classes are passed by reference, meaning changes made to one instance affect all references to it.
  • Mutable by nature: Changes can propagate across references, which is useful when you need shared state.
  • Managed by ARC: Classes come with ARC, which tracks and manages the lifecycle of objects.
  • Better for shared or complex data: Ideal for cases where objects need to be shared across different parts of your app or involve relationships.

SwiftUI: Using Structs for Models

In most SwiftUI applications, structs are the default choice for models. Since SwiftUI is designed around declarative programming principles, structs’ value semantics align perfectly with SwiftUI’s philosophy.

Here’s an example of using a struct for a simple Person model:

struct Person {
    var name: String
    var age: Int
}

Why Use Structs in SwiftUI?

  1. Performance: Structs are faster and more efficient due to their value semantics.
  2. Predictability: Since structs are copied when passed, each instance is independent, which makes it easier to reason about your code.
  3. Concurrency Safety: Structs’ immutability (unless explicitly mutable) helps avoid issues when working with concurrency.

In simple terms, structs are great for SwiftUI models when you:

  • Don’t need shared state between views or components.
  • Are modeling simple data that doesn’t rely on persistence frameworks like SwiftData.

SwiftData and the Case for Classes

While structs are great for lightweight models, the need for classes becomes apparent when working with SwiftData (or other persistence frameworks, like Core Data). SwiftData requires reference semantics, making classes necessary for models to ensure data consistency and lifecycle management.

Here’s an example of a Person model in SwiftData:

import SwiftData

@Model
class Person {
    var name: String
    var age: Int
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

Why Use Classes with SwiftData?

  1. Reference Semantics: SwiftData needs objects to be shared across multiple components. If you update the Person class in one part of the app, the changes will automatically reflect everywhere it is referenced.
  2. Persistence: SwiftData (and Core Data) manages object graphs, relationships, and persistence through reference types.
  3. Complex Relationships: If your model has relationships (e.g., a Person having a list of friends), classes are better suited to managing these references without duplicating data.

Thus, classes are essential when:

  • You’re using SwiftData or other persistence frameworks that need managed object contexts.
  • Your data is shared across multiple parts of the app, and you want to observe and react to changes.
  • You’re modeling complex relationships between objects.

When to Use Structs vs. Classes: A Recap

Scenario Use Structs Use Classes
Simple data models Yes No
Immutable data Yes No
Lightweight, performance-sensitive Yes No
Need shared, mutable state No Yes
Using SwiftData or Core Data No Yes
Data with complex relationships No Yes
Concurrency safety Yes No

Final Thoughts

In modern SwiftUI development (2024 and beyond), structs are the default choice for most models due to their performance and value semantics. However, when working with frameworks like SwiftData—where persistence, shared state, and reference management are essential—classes become a necessity.

To summarize:

  • Use structs for lightweight, simple, and self-contained models that don’t require shared state.
  • Use classes when working with SwiftData or any scenario where reference semantics and persistence are required.

For more about Classes and Structs read this Article

Understanding when to use structs vs. classes will help you design more efficient and scalable SwiftUI applications. Happy coding!

This Post Has 0 Comments

Leave a Reply

Back To Top
Search