ProgramaciónDesarrollador iOS

Explique las diferencias entre value types y reference types en Swift. ¿Cuándo se debe usar cada uno de ellos?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

En Swift existen dos tipos de datos principales: value types (tipos de valor) y reference types (tipos de referencia).

  • Value types. Incluyen estructuras (struct), enumeraciones (enum) y tipos básicos como Int, Double, Bool. Al pasar o asignar un valor, se copia, es decir, los cambios en la copia no afectan al original.
  • Reference types. Son clases (class) y tipos asociados. Al pasar, no se copia el objeto en sí, sino la referencia a él, por lo que los cambios a través de una referencia son visibles a través de otras.

Cuándo usar:

  • Utiliza value types si deseas que los datos sean copias independientes (por ejemplo, CGPoint, CGSize, modelos que no deben compartir estado).
  • Reference types son adecuados si se requiere compartir estado entre objetos (por ejemplo, gerentes, controladores, servicios).

Ejemplo:

struct Point { var x: Int var y: Int } class Person { var name: String init(name: String) { self.name = name } } var p1 = Point(x: 0, y: 0) var p2 = p1 p2.x = 10 // p1.x seguirá siendo 0 var person1 = Person(name: "Alex") var person2 = person1 person2.name = "Sam" // person1.name también se convertirá en "Sam"

Pregunta engañosa.

¿Cuál es la diferencia de let para struct y class? ¿Es una instancia de class, creada con let, completamente inmutable?

Respuesta:

Para los value types (struct), let hace que el objeto y sus propiedades sean inmutables.

Para los reference types (class), let prohíbe reasignar la referencia, pero no protege las propiedades del objeto. Se pueden cambiar, a menos que estén declaradas como let dentro de la clase.

Ejemplo:

class Box { var value: Int init(value: Int) { self.value = value } } let box = Box(value: 10) box.value = 20 // ¡OK! // box = Box(value: 30) // Error: no se puede reasignar box

Ejemplos de errores reales debido al desconocimiento de las sutilezas del tema.


Historia

En una aplicación de pago, el modelo de transacción se definió como una clase, aunque no debería haber estado compartiendo estado. Surgió un bug: al trabajar simultáneamente con una lista de transacciones, se producían ediciones impredecibles en los datos de diferentes partes de la interfaz. Se decidió cambiar los modelos a struct para que cada componente trabajara con su propia copia.


Historia

En un proyecto, se almacenaban las configuraciones del usuario en una clase, creyendo que los valores se copiaban al pasarlos. Al cambiar datos, una pantalla afectaba accidentalmente a otra, ya que ambas trabajaban con la misma referencia al objeto.


Historia

En el módulo de serialización, los datos del modelo se declararon como reference type, lo que causaba que cualquier cambio dañara el estado en caché. Después de cambiar a value types, el problema desapareció: los datos se volvieron independientes en cada operación.