certmundo.
es‑mx

7 min de lectura

¿Cómo usar clases y estructuras en Swift?

Las clases (class) y las estructuras (struct) son plantillas que te permiten modelar datos del mundo real dentro de tu app iOS.

Con ellas puedes representar cosas como un producto de Mercado Libre, un usuario de Liverpool o un pedido de Bimbo. Ambas agrupan propiedades y métodos en un solo lugar.


Diferencias fundamentales entre class y struct

Antes de escribir código, necesitas entender una diferencia clave: el comportamiento al copiarse.

  • Una struct es un tipo por valor. Cuando la asignas a otra variable, Swift crea una copia independiente.
  • Una class es un tipo por referencia. Cuando la asignas a otra variable, ambas variables apuntan al mismo objeto en memoria.

Esta diferencia cambia cómo se comporta tu app. Elegir mal puede causar errores difíciles de detectar.


Sintaxis de una struct

La estructura básica de una struct es:

struct NombreDelTipo {
    var propiedad1: Tipo
    var propiedad2: Tipo

    func nombreDelMetodo() -> Tipo {
        // lógica
    }
}

Todos los nombres de tipos —tanto struct como class— se escriben en UpperCamelCase: la primera letra de cada palabra en mayúscula.


Ejemplo 1: struct para un producto de Mercado Libre

Imagina que tu app muestra productos. Crea una struct llamada Producto:

struct Producto {
    var nombre: String
    var precio: Double
    var disponible: Bool

    func descripcion() -> String {
        let estado = disponible ? "En stock" : "Agotado"
        return "\(nombre) — $\(precio) — \(estado)"
    }
}

Ahora crea una instancia (un objeto concreto basado en la plantilla):

var tenis = Producto(nombre: "Tenis Running", precio: 1200, disponible: true)
print(tenis.descripcion())
// Salida: Tenis Running — $1,200 — En stock

Fíjate en el inicializador automático: Swift genera init gratis para las struct. Solo pasas los valores en el orden de las propiedades.


Sintaxis de una class

class NombreDelTipo {
    var propiedad1: Tipo
    var propiedad2: Tipo

    init(propiedad1: Tipo, propiedad2: Tipo) {
        self.propiedad1 = propiedad1
        self.propiedad2 = propiedad2
    }

    func nombreDelMetodo() {
        // lógica
    }
}

A diferencia de struct, una class no genera init automático. Debes escribirlo tú mismo. Usa self. para distinguir entre la propiedad del objeto y el parámetro del init.


Ejemplo 2: class para un usuario de Liverpool

Cuando varios módulos de tu app necesitan compartir y modificar el mismo objeto, usa class:

class Usuario {
    var nombre: String
    var saldo: Double

    init(nombre: String, saldo: Double) {
        self.nombre = nombre
        self.saldo = saldo
    }

    func agregarSaldo(_ cantidad: Double) {
        saldo += cantidad
        print("Nuevo saldo de \(nombre): $\(saldo)")
    }
}

Crea una instancia y modifícala:

let clienta = Usuario(nombre: "Sofía", saldo: 5000)
clienta.agregarSaldo(2500)
// Salida: Nuevo saldo de Sofía: $7,500

Nota importante: aunque clienta es constante (let), puedes modificar sus propiedades porque es una referencia. Con struct, esto no funciona así.


Tipo por valor vs. tipo por referencia en la práctica

Este bloque de código muestra la diferencia de forma directa:

// Con struct (tipo por valor)
var pedidoA = Producto(nombre: "Leche Bimbo", precio: 35, disponible: true)
var pedidoB = pedidoA       // Se crea una COPIA
pedidoB.precio = 40
print(pedidoA.precio)       // 35 — no cambió
print(pedidoB.precio)       // 40

// Con class (tipo por referencia)
let usuarioX = Usuario(nombre: "Carlos", saldo: 3000)
let usuarioY = usuarioX     // Apuntan al MISMO objeto
usuarioY.agregarSaldo(1500)
print(usuarioX.saldo)       // 4,500 — sí cambió

Esta es la razón principal por la que Swift prefiere struct para datos simples y class para objetos compartidos en la app.


Propiedades calculadas

Tanto struct como class soportan propiedades calculadas: valores que se derivan de otras propiedades, sin almacenarse por separado.

struct Pedido {
    var subtotal: Double
    var descuento: Double

    var total: Double {
        return subtotal - descuento
    }
}

let pedidoFEMSA = Pedido(subtotal: 8500, descuento: 500)
print(pedidoFEMSA.total)
// Salida: 8000.0

La propiedad total no ocupa espacio en memoria extra; se calcula cada vez que la lees.


Cuándo usar struct y cuándo usar class

Situación Usa
Modelar datos simples (producto, dirección, precio) struct
Compartir estado entre varias partes de la app class
Necesitas herencia (un tipo que extiende otro) class
Trabajas con SwiftUI (la mayoría de los casos) struct
Integras con frameworks de Apple como UIViewController class
El objeto tiene un ciclo de vida claro (abrir/cerrar sesión) class

En SwiftUI, casi todo el código de la interfaz usa struct. En UIKit, las vistas y controladores son class.


Ejemplo 3: Combinando struct y class en una app de FEMSA

Una app real mezcla ambos. Los datos son struct; el controlador que los gestiona es class:

struct Sucursal {
    var nombre: String
    var ciudad: String
    var ventasDiarias: Double
}

class GestorDeSucursales {
    var sucursales: [Sucursal] = []

    func agregar(_ sucursal: Sucursal) {
        sucursales.append(sucursal)
    }

    func totalVentas() -> Double {
        return sucursales.reduce(0) { $0 + $1.ventasDiarias }
    }
}

let gestor = GestorDeSucursales()
gestor.agregar(Sucursal(nombre: "OXXO Reforma", ciudad: "CDMX", ventasDiarias: 18500))
gestor.agregar(Sucursal(nombre: "OXXO Monterrey", ciudad: "MTY", ventasDiarias: 14200))
print(gestor.totalVentas())
// Salida: 32700.0

Esta separación mantiene el código limpio y fácil de mantener.


Errores comunes

1. Olvidar el init en una class

Si declaras una class con propiedades sin valores por defecto y no escribes init, el compilador marca error. La solución es siempre definir init o asignar valores por defecto.

// ❌ Error
class Empleado {
    var nombre: String   // No tiene valor por defecto ni init
}

// ✅ Correcto
class Empleado {
    var nombre: String
    init(nombre: String) { self.nombre = nombre }
}

2. Modificar una struct en una constante

Si declaras una instancia de struct con let, sus propiedades son inmutables aunque estén declaradas con var dentro de la struct.

let producto = Producto(nombre: "Pan Bimbo", precio: 28, disponible: true)
producto.precio = 30  // ❌ Error: no puedes mutar una struct constante

var productoCambiable = Producto(nombre: "Pan Bimbo", precio: 28, disponible: true)
productoCambiable.precio = 30  // ✅ Correcto

3. Confundir referencia compartida con copia

Este error genera bugs silenciosos. Cuando asignas una class a otra variable, no obtienes una copia. Si necesitas una copia real, debes implementar un método clone() o usar struct.


Resumen de sintaxis

Característica struct class
Tipo Por valor Por referencia
init automático ✅ Sí ❌ No
Herencia ❌ No ✅ Sí
mutating para métodos que modifican propiedades Necesario No necesario
Uso en SwiftUI Principal Secundario

Puntos clave

  • Usa struct para datos simples e independientes; usa class cuando varios módulos deban compartir el mismo objeto.
  • Las struct son tipo por valor: cada asignación crea una copia. Las class son tipo por referencia: todas las variables apuntan al mismo objeto.
  • Las struct generan init automáticamente. Las class requieren que lo escribas con self..
  • Las propiedades calculadas derivan su valor de otras propiedades y funcionan en ambos tipos.
  • En SwiftUI, la mayoría del código de interfaz usa struct. En UIKit, los controladores usan class.

Puntos clave

  • `struct` es tipo por valor: cada asignación crea una copia independiente. Úsala para modelar datos simples como productos, precios o direcciones.
  • `class` es tipo por referencia: todas las variables que apuntan al mismo objeto comparten sus cambios. Úsala cuando varias partes de la app deban modificar el mismo estado.
  • Las `struct` generan un `init` automático gratis. Las `class` requieren que escribas `init` manualmente usando `self.` para asignar cada propiedad.
  • Las propiedades calculadas (`var total: Double { ... }`) derivan su valor de otras propiedades sin ocupar memoria adicional, y funcionan en `struct` y `class`.
  • En SwiftUI casi toda la interfaz se construye con `struct`. En UIKit, los controladores y vistas heredan de `class` de Apple como `UIViewController`.

Comparte esta lección: