Dominar el framework (SwiftUI o UIKit) es solo la mitad de la batalla. En las entrevistas técnicas de alto nivel, los reclutadores necesitan saber si entiendes el lenguaje que hay debajo. ¿Sabes cómo gestiona Swift la memoria? ¿Entiendes la diferencia real entre struct y class? ¿Dominas la concurrencia moderna?
Aquí te presento la colección definitiva de preguntas sobre Swift, dividida por niveles de dificultad. Cubrimos las 165 preguntas esenciales.
🟢 Nivel 1: Conceptos Básicos y Sintaxis
Estas preguntas son el filtro inicial. Si fallas aquí, la entrevista suele terminar.
- ¿Qué es Swift? Es un lenguaje de programación multiparadigma, de tipado fuerte, compilado y de código abierto desarrollado por Apple. Es seguro, rápido y expresivo.
- ¿Cuál es la diferencia entre
varylet?vardeclara variables mutables (su valor puede cambiar).letdeclara constantes (inmutables una vez asignadas). - ¿Qué es la inferencia de tipos (Type Inference)? La capacidad del compilador de Swift para deducir el tipo de dato de una variable basándose en su valor inicial, sin necesidad de escribirlo explícitamente.
- ¿Qué es un
Optionalen Swift? Es un tipo que representa la posibilidad de que una variable tenga un valor o no tenga nada (nil). Se define con?. - ¿Qué es “Type Safety” (Seguridad de tipos)? Swift te obliga a ser claro con los tipos de datos. No puedes asignar un
Stringa una variableIntpor accidente; el compilador lanzará un error. - ¿Qué es una Tupla? Un grupo de valores combinados en un solo valor compuesto. Pueden ser de diferentes tipos. Ej:
(404, "Not Found"). - ¿Qué es un
typealias? Permite dar un nombre alternativo a un tipo existente para hacer el código más legible. Ej:typealias AudioSample = UInt16. - ¿Cuál es la diferencia entre
FloatyDouble?Floates un número de punto flotante de 32 bits (menos precisión).Doublees de 64 bits (mayor precisión y es el default en Swift). - ¿Qué son los Generics (Genéricos)? Código flexible y reutilizable que puede trabajar con cualquier tipo de dato, sujeto a requisitos que tú definas (como
Array<Element>). - ¿Qué es
AnyyAnyObject?Anypuede representar una instancia de cualquier tipo (funciones, structs, clases).AnyObjectsolo puede representar instancias de clases.
🔵 Nivel 2: Colecciones y Control de Flujo
- ¿Diferencia principal entre
ArrayySet? UnArrayes ordenado y permite duplicados. UnSetes desordenado y garantiza que cada elemento sea único. - ¿Qué protocolo deben cumplir los elementos de un
Seto las claves de unDictionary? Deben conformar aHashable. - ¿Qué es un Diccionario? Una colección desordenada de asociaciones clave-valor.
- ¿Qué hace la sentencia
guard? Se usa para transferir el control fuera de un ámbito si no se cumple una condición. Es ideal para “early exit” (salida temprana) y evitar la pirámide de indentación. - ¿Diferencia entre
if letyguard let?if letdesenpaqueta el opcional solo dentro de su bloque{}.guard letdesenpaqueta el opcional para el resto del ámbito actual, y requiere unelse { return/throw }si falla. - ¿Qué significa que el
switchen Swift debe ser exhaustivo? Que debe cubrir todos los casos posibles del valor evaluado, o incluir un casodefault. - ¿Qué es el “Range Operator”
...y..<?...es rango cerrado (incluye el final)...<es rango semi-abierto (excluye el valor final). - ¿Cómo se itera sobre un diccionario? Usando
for (key, value) in dictionary. - ¿Qué es
stride? Una función para crear secuencias numéricas con saltos específicos (ej. de 0 a 10 de 2 en 2). - ¿Qué hace
breaken un bucle? Termina la ejecución del bucle inmediatamente. - ¿Qué hace
continueen un bucle? Salta la iteración actual y pasa a la siguiente.
🟠 Nivel 3: Estructuras (Structs) vs Clases (Classes)
El tema más preguntado en la historia de Swift.
- ¿Cuál es la diferencia fundamental entre
structyclass? Lasstructsson Value Types (Tipos de Valor). Lasclassesson Reference Types (Tipos de Referencia). - Explica “Value Type”. Cuando asignas o pasas una struct, se crea una copia de los datos. Modificar la copia no afecta al original.
- Explica “Reference Type”. Cuando asignas o pasas una clase, se pasa una referencia (puntero) a la misma instancia en memoria. Modificar una afecta a todas las referencias.
- ¿Qué tienen las Clases que no tengan las Structs? Herencia, desinicializadores (
deinit), identidad (===) y conteo de referencias (ARC). - ¿Qué tienen las Structs que no tengan las Clases? Inicializadores miembro a miembro automáticos (
memberwise init) y son más ligeras en memoria (Stack vs Heap). - ¿Cuándo deberías usar una Struct? Por defecto. Úsala para modelos de datos simples, valores que se comportan como datos primitivos y cuando no necesitas identidad compartida.
- ¿Qué significa la palabra clave
mutatingen una Struct? Indica que un método dentro de la struct va a modificar sus propias propiedades. Es necesario porque las structs son inmutables por defecto. - ¿Los
ArrayyStringen Swift son clases o estructuras? Son Estructuras (structs). - ¿Qué es “Copy on Write” (COW)? Es una optimización de Swift para colecciones (como Arrays). Aunque son tipos de valor, la copia real solo ocurre cuando se modifica el dato, no cuando se asigna, ahorrando rendimiento.
🟣 Nivel 4: Opcionales a fondo
- ¿Qué es “Optional Binding”? El proceso de comprobar si un opcional tiene valor y extraerlo a una constante/variable segura (usando
if letoguard let). - ¿Qué es “Optional Chaining” (
?.)? Permite llamar a propiedades o métodos en un opcional que podría ser nil. Si es nil, la cadena se detiene y devuelve nil; si no, continúa. - ¿Qué es el operador “Nil Coalescing” (
??)? Proporciona un valor por defecto en caso de que el opcional sea nil. Ej:let nombre = usuario.nombre ?? "Invitado". - ¿Qué es “Force Unwrapping” (
!)? Extrae el valor del opcional a la fuerza. Si esnil, la app crashea. Solo debe usarse si estás 100% seguro. - ¿Qué es un “Implicitly Unwrapped Optional” (
Type!)? Un opcional que se asume que siempre tiene valor después de su primera asignación. No requiere desenpaquetado explícito al usarse, pero crashea si es nil (común en@IBOutlets). - ¿Puede un opcional contener
nilcomo valor válido dentro de otro opcional? Sí,Double Optional(String??).
🔴 Nivel 5: Funciones y Closures
- ¿Qué es un Closure? Son bloques de funcionalidad autónomos que pueden ser pasados y utilizados en tu código. Similar a las lambdas en otros lenguajes.
- ¿Cuál es la sintaxis de una “Trailing Closure”? Si el último parámetro de una función es un closure, puedes escribirlo fuera de los paréntesis de la llamada.
array.map { $0 * 2 }. - ¿Qué significan
$0,$1en un closure? Son nombres abreviados para los argumentos del closure (Shorthand argument names). - ¿Qué es
@escapingen un closure? Indica que el closure puede ejecutarse después de que la función retorne (ej. una llamada asíncrona de red). Por defecto sonnon-escaping. - ¿Qué es
@autoclosure? Convierte una expresión pasada como argumento automáticamente en un closure. Permite escribirassert(condition)en lugar deassert({ condition }). - ¿Qué es una función variádica? Una función que acepta cero o más valores de un tipo específico (ej.
print(...)). Se escribe con.... - ¿Qué son los parámetros
inout? Permiten que una función modifique el valor de una variable pasada como parámetro (paso por referencia). - ¿Las funciones son tipos de primera clase en Swift? Sí, pueden asignarse a variables, pasarse como argumentos y retornarse desde otras funciones.
- ¿Qué es una función de orden superior (Higher Order Function)? Una función que toma otra función como argumento o devuelve una. Ejemplos:
map,filter,reduce.
⚫ Nivel 6: Propiedades y Métodos
- ¿Diferencia entre “Stored Property” y “Computed Property”? Stored: Almacena un valor en memoria. Computed: Calcula el valor cada vez que se accede a ella (tiene getter y opcionalmente setter).
- ¿Qué son los “Property Observers”?
willSet(se ejecuta justo antes de cambiar el valor) ydidSet(se ejecuta justo después). - ¿Qué es una propiedad
lazy? Una propiedad cuyo valor inicial no se calcula hasta la primera vez que se usa. Debe servar. - ¿Qué significa
static? Define una propiedad o método que pertenece al tipo en sí, no a una instancia. - ¿Diferencia entre
staticyclassen métodos? Ambos definen métodos de tipo.staticno se puede sobrescribir en subclases (es final),classsí permiteoverride. - ¿Qué es un Singleton y cómo se crea en Swift? Un patrón donde solo existe una instancia de una clase.
static let shared = MyClass(), con unprivate init().
⚪ Nivel 7: Protocolos y Extensiones (POP)
Swift es el primer lenguaje orientado a protocolos.
- ¿Qué es un Protocolo? Un “contrato” que define un esquema de métodos, propiedades y requisitos que una clase, estructura o enumeración debe cumplir.
- ¿Qué es una Extensión? Permite añadir funcionalidad a un tipo existente (incluso si no tienes el código fuente original), como nuevos métodos o propiedades calculadas (no almacenadas).
- ¿Qué son las “Protocol Extensions”? Permiten dar una implementación por defecto a los métodos de un protocolo. Es la base de la Programación Orientada a Protocolos.
- ¿Qué es un “Associated Type” en un protocolo? Un marcador de posición para un tipo que se definirá cuando el protocolo sea adoptado. Se usa
associatedtype. - ¿Puede una extensión añadir propiedades almacenadas (Stored Properties)? No, solo calculadas.
- ¿Qué significa
Codable? Es untypealiasde los protocolosEncodableyDecodable. Permite convertir objetos a/desde JSON u otros formatos. - ¿Qué es
Equatable? Un protocolo que permite comparar dos instancias usando==. - ¿Qué es
Hashable? Un protocolo que permite que una instancia genere un valor hash integer, necesario para ser clave en Diccionarios o elemento en Sets. - ¿Qué es
CaseIterableen enums? Genera automáticamente una colección de todos los casos del enum (allCases).
🟤 Nivel 8: Gestión de Memoria (ARC)
Crucial para evitar Memory Leaks.
- ¿Qué es ARC? Automatic Reference Counting. Es el sistema de Swift para rastrear y gestionar el uso de memoria de la app, liberando instancias de clases que ya no se usan.
- ¿Qué es un “Retain Cycle” (Ciclo de retención)? Cuando dos instancias se apuntan mutuamente con referencias fuertes (Strong), impidiendo que ARC las libere, causando fugas de memoria.
- ¿Diferencia entre
strong,weakyunowned?strong: Incrementa el contador de referencias (por defecto).weak: No incrementa el contador. Debe ser opcional (var?) porque puede volverse nil.unowned: No incrementa el contador. No es opcional (se asume que siempre tendrá valor). Si el objeto muere y accedes, crashea.
- ¿Cuándo usar
unowneden lugar deweak? Cuando la otra instancia tiene el mismo tiempo de vida o mayor (ej. Cliente y Tarjeta de Crédito; la tarjeta no existe sin cliente). - ¿Qué es una “Capture List” en closures
[weak self]? Define cómo el closure captura las variables externas.[weak self]evita ciclos de retención si el closure es propiedad deselfyselfes usado dentro del closure. - ¿Las Structs usan ARC? No, porque son Value Types (se gestionan en el Stack, no en el Heap). ARC es solo para clases.
🌓 Nivel 9: Manejo de Errores
- ¿Qué protocolo debe cumplir un tipo para ser lanzado como error? Protocolo
Error. - ¿Qué significan
try,try?ytry!?try: Lanza el error si ocurre (debe estar en do-catch o función throws).try?: Si falla, devuelvenil(ignora el error).try!: Si falla, crashea la app (aseguras que no fallará).
- ¿Qué hace
defer? Define un bloque de código que se ejecutará justo antes de que el ámbito actual finalice (no importa si termina por return, error o final normal). Útil para cerrar archivos o liberar recursos. - ¿Qué es el tipo
Result? Un enum con dos casos:.success(Value)y.failure(Error). Muy usado en closures de completado.
✨ Nivel 10: Concurrencia Moderna (Swift 5.5+)
- ¿Qué es
async/await? Una sintaxis para escribir código asíncrono que parece síncrono, eliminando el “Callback Hell”. - ¿Qué es un
Actor? Un tipo de referencia (como una clase) que protege su estado mutable garantizando que solo un hilo acceda a sus datos a la vez. Es “Thread Safe” por defecto. - ¿Qué es
@MainActor? Un atributo que asegura que la función o clase se ejecute siempre en el Hilo Principal (Main Thread), crucial para actualizaciones de UI. - ¿Qué es una
Task? Una unidad de trabajo asíncrono. Permite llamar funcionesasyncdesde un contexto síncrono. - ¿Qué es
TaskGroup? Permite crear múltiples tareas asíncronas dinámicamente y esperar a que todas terminen (concurrencia estructurada).
🧩 Nivel 11: Control de Acceso
- ¿Cuáles son los niveles de acceso en Swift (del más restrictivo al más abierto)?
private,fileprivate,internal(default),public,open. - ¿Diferencia entre
privateyfileprivate?private: Solo visible dentro del alcance de declaración (ej. dentro de la clase).fileprivate: Visible en todo el archivo.swiftactual. - ¿Diferencia entre
publicyopen? Ambos permiten acceso desde otros módulos.openpermite que la clase sea subclaseada y sus métodos sobrescritos fuera del módulo.publicno.
🛠 Nivel 12: Avanzado y Runtime
- ¿Qué es el “Method Dispatch”? El mecanismo que usa el programa para saber qué operación ejecutar.
- ¿Tipos de Dispatch en Swift? Static Dispatch (Directo, muy rápido, Structs), Table Dispatch (Clases), Message Dispatch (Objective-C).
- ¿Cómo logras Static Dispatch en una clase? Usando
finaloprivate, lo que impide el override. - ¿Qué es KVO (Key-Value Observing)? Un patrón (heredado de Obj-C) para notificar a objetos cuando cambian propiedades de otros objetos. Requiere heredar de
NSObjecty usar@objc dynamic. - ¿Qué es
some(Opaque Types)? Indica que retornas un tipo específico que conforma a un protocolo, pero ocultas cuál es exactamente. - ¿Qué es
associatedtype? Define un tipo genérico dentro de un protocolo. - ¿Qué son los “Property Wrappers”? Tipos que envuelven una propiedad para añadir lógica en su lectura/escritura (ej.
@State,@Published,@UserDefault). - ¿Qué hace
final? Impide que una clase sea heredada o que un método sea sobrescrito. Mejora el rendimiento. - ¿Qué son los “Raw Values” en un Enum? Valores pre-poblados (como Int o String) asignados a cada caso del enum. Deben ser únicos.
- ¿Qué son los “Associated Values” en un Enum? Valores que se adjuntan a un caso del enum en el momento de crear la instancia (pueden ser diferentes cada vez).
- ¿Qué es
autoreleasepool? Un bloque que permite liberar objetos temporales creados en bucles intensivos inmediatamente, reduciendo el pico de memoria. - ¿Cómo comparas dos tuplas? El operador
==funciona automáticamente si los elementos dentro de la tupla sonEquatable(hasta 6 elementos).
🧠 Nivel 13: Swift Functional Programming
- ¿Qué hace
map? Transforma cada elemento de una colección usando una función y devuelve un nuevo array. - ¿Qué hace
compactMap? Igual que map, pero elimina los resultados que seannily desenpaqueta los opcionales restantes. - ¿Qué hace
flatMap? Aplana una colección de colecciones (ej.[[1,2], [3,4]]->[1,2,3,4]). - ¿Qué hace
reduce? Combina todos los elementos de una colección en un único valor (ej. sumar todos los números). - ¿Qué hace
filter? Devuelve un array solo con los elementos que cumplen una condición. - ¿Qué hace
zip? Combina dos secuencias en una secuencia de pares (tuplas). - ¿Qué es el “Currying” (aunque Swift ya no lo soporta sintácticamente por defecto)? Convertir una función de múltiples argumentos en una secuencia de funciones de un solo argumento.
- ¿Swift es un lenguaje funcional? No puramente, pero tiene fuerte soporte para programación funcional (funciones de primera clase, inmutabilidad, HOF).
🔍 Nivel 14: Debugging y Miscelánea
- ¿Qué es
#if DEBUG? Una directiva de compilación condicional para ejecutar código solo en modo desarrollo. - ¿Qué diferencia hay entre
Self(mayúscula) yself(minúscula)?self: la instancia actual.Self: el tipo de la instancia actual (útil en protocolos).
🧬 Nivel 15: Genéricos Avanzados y Tipos Existenciales
Esta es la barrera más común entre un Mid y un Senior.
- ¿Qué es “Type Erasure” (Borrado de Tipos) y por qué lo necesitamos? Es un patrón para trabajar con protocolos que tienen
associatedtype(tipos asociados). Como esos protocolos no se pueden usar como tipos variables directos, se envuelven en una clase/struct genérica (ej.AnyPublisher,AnyView) que “oculta” el tipo concreto subyacente. - ¿Cuál es la diferencia entre
some Protocolyany Protocol(Swift 5.7+)?some(Opaque Type) garantiza que el tipo es fijo y concreto, pero oculto al llamador (rendimiento estático).any(Existential Type) es una caja dinámica que puede contener cualquier tipo que cumpla el protocolo, permitiendo cambiar el valor en tiempo de ejecución (tiene costo de rendimiento). - ¿Qué son los “Opaque Return Types”? Funciones que retornan
some View(osome Protocol). Permiten al compilador conocer el tipo exacto para optimizaciones, pero obligan al desarrollador a devolver siempre el mismo tipo concreto dentro de la función. - ¿Qué significa la restricción
whereen genéricos? Permite definir requisitos adicionales para los tipos genéricos. Ej:func comparar<T>(a: T, b: T) where T: Equatable. - ¿Qué es la “Conditional Conformance” (Conformidad Condicional)? Permite que un tipo genérico cumpla un protocolo solo si sus tipos internos también lo cumplen. Ej:
ArrayesCodablesolo si sus elementos (Element) sonCodable. - ¿Qué es un “Primary Associated Type” en protocolos? Sintaxis ligera (
Protocol<Type>) introducida en Swift 5.7 para restringir tipos asociados. Ej:func procesar(lista: some Collection<String>). - ¿Por qué los protocolos con
Selfoassociatedtypeno se podían usar como tipos hasta hace poco? Porque el compilador no podía saber cuánto espacio en memoria reservar para ellos sin conocer el tipo concreto. Ahoraanyresuelve esto creando una “caja” (existential container). - ¿Qué es la covarianza y contravarianza en Swift? Se refiere a cómo los subtipos se relacionan en tipos complejos. Swift es generalmente invariante en genéricos (un
Array<Cat>no es unArray<Animal>), pero las funciones tienen reglas especiales de subtipado en sus retornos y argumentos.
🛠 Nivel 16: Punteros y Swift “Unsafe”
Swift es seguro, pero te permite ser peligroso si lo necesitas para interactuar con C o optimizar al máximo.
- ¿Qué significa “Unsafe” en Swift (ej.
UnsafePointer)? Significa que Swift desactiva sus comprobaciones de seguridad (como límites de array o gestión automática de memoria). Si cometes un error aquí, causas un crash o corrupción de memoria. - Diferencia entre
UnsafePointer,UnsafeMutablePointer,UnsafeRawPointeryUnsafeBufferPointer.Pointer: Solo lectura, tipado (UnsafePointer<Int>).Mutable: Lectura y escritura.Raw: Sin tipar (bytes puros,void*en C). No sabe qué tipo de dato hay, solo ve memoria.Buffer: Funciona como un array (tienecount) sobre una región de memoria continua.
- ¿Qué es
withUnsafeBytes? Un método para acceder temporalmente a la representación en bytes de un dato (como un Array o Data) de forma segura dentro de un closure. - ¿Qué es el “Memory Layout” (alineación, tamaño y stride)?
size: Espacio real que ocupan los datos.alignment: Regla de memoria (ej. debe empezar en múltiplo de 8).stride: Distancia entre el inicio de un elemento y el siguiente en un array (incluye padding).
- ¿Cómo conviertes una cadena de Swift a un
char *de C? Swift hace el puente automático en interoperabilidad, o puedes usarstring.withCString { ptr in ... }. - ¿Qué es un “Dangling Pointer”? Un puntero que apunta a una dirección de memoria donde el objeto ya ha sido liberado.
⚙️ Nivel 17: Compilador y Rendimiento
- ¿Cuáles son las fases principales de compilación de Swift? Parsing (Código fuente) -> AST (Árbol sintáctico) -> SIL (Swift Intermediate Language) -> LLVM IR -> Código Máquina.
- ¿Qué es SIL (Swift Intermediate Language)? Un lenguaje intermedio específico de Swift donde ocurren optimizaciones de alto nivel (como ARC optimization, devirtualization, generics specialization) antes de pasar a LLVM.
- ¿Qué es “Whole Module Optimization” (WMO)? Un modo de compilación donde el compilador analiza todo el módulo a la vez (en lugar de archivo por archivo), permitiendo mejores optimizaciones como inlining agresivo y eliminación de código muerto.
- ¿Qué es “Method Swizzling”? Una técnica del runtime de Objective-C (posible en Swift heredando de NSObject) para cambiar la implementación de un método en tiempo de ejecución.
- ¿Qué es “Dynamic Dispatch” vs “Static Dispatch” vs “Witness Table”?
- Static: La dirección de la función se conoce al compilar (rápido).
- Dynamic (V-Table): Se busca en una tabla en tiempo de ejecución (Clases).
- Witness Table: Usada para Protocolos.
- Message Dispatch: Runtime de Obj-C (más lento, pero muy flexible).
- ¿Cómo reduce Swift el costo de ARC? El compilador (en la fase SIL) analiza el código y elimina llamadas redundantes a
retainyrelease. - ¿Qué es la “Generic Specialization”? El compilador crea versiones específicas de una función genérica para tipos concretos (ej. crea una versión de
sumar<Int>y otra desumar<Float>) para evitar la sobrecarga de la abstracción. - ¿Qué atributo usas para forzar que una función sea “inlined”?
@inline(__always).
🍏 Nivel 18: Interoperabilidad (Obj-C y C++)
- ¿Qué hace el modificador
@objc? Expone un método o propiedad de Swift al runtime de Objective-C. - ¿Qué significa
dynamicen Swift? Fuerza a que el método utilice el “Message Dispatch” de Objective-C en lugar del despacho estático o de tabla virtual de Swift. Es necesario para KVO y Swizzling. - ¿Puede un
structde Swift ser usado en Objective-C? No. Solo las clases que heredan deNSObject(o clases Swift puras con@objcque no usen features exclusivas de Swift) son visibles. - ¿Qué es un “Bridging Header”? Un archivo
.hque permite importar cabeceras de Objective-C para que sean visibles y usables desde el código Swift. - ¿Qué es C++ Interop en Swift 5.9? La capacidad nativa de importar y usar tipos de C++ directamente en Swift sin necesidad de crear “wrappers” en Objective-C++.
📦 Nivel 19: Swift Package Manager (SPM) y Modularización
- ¿Cuál es la diferencia entre una Librería y un Framework? Técnicamente, una librería es código compilado (estático o dinámico). Un framework es una estructura de directorios que empaqueta la librería junto con recursos (imágenes, headers).
- ¿Librería Estática vs Dinámica?
- Estática: El código se copia dentro del ejecutable de tu app (aumenta el tamaño de la app, inicio más rápido).
- Dinámica: El código vive fuera del ejecutable y se carga al iniciar (reduce tamaño app, inicio puede ser más lento, permite compartir código entre extensiones).
- ¿Qué es
Package.swift? El archivo de manifiesto que define las dependencias, targets y productos de un paquete SPM. - ¿Cómo gestionas recursos (imágenes/JSON) en un paquete SPM? Usando la carpeta
Resourcesy accediendo medianteBundle.module.
🔮 Nivel 20: Swift Moderno (5.9, 6.0) y Macros
- ¿Qué es una Macro en Swift (
#Predicado,@Model)? Código que se ejecuta en tiempo de compilación para generar más código Swift, reduciendo el “boilerplate”. - ¿Diferencia entre Freestanding Macro y Attached Macro?
- Freestanding: Aparecen por sí solas (ej.
#warning("Cuidado")). - Attached: Se adjuntan a una declaración (ej.
@Observableen una clase).
- Freestanding: Aparecen por sí solas (ej.
- ¿Qué es el “Ownership Manifesto” (Propiedad de memoria)? Un conjunto de características para controlar granularmente la memoria sin el overhead de ARC, acercándose a Rust.
- ¿Qué hacen las palabras clave
consumingyborrowing?consuming: La función toma la propiedad del valor (y es responsable de destruirlo).borrowing: La función toma “prestado” el valor (acceso de lectura) sin incrementar el contador de referencias.
- ¿Qué es un
Noncopyable Type(~Copyable)? Un tipo (struct o enum) que no se puede copiar. Útil para recursos únicos como descriptores de archivos o mutexes. - ¿Qué es “Actor Reentrancy” y qué problema causa? Un actor puede suspender una función (
await) y empezar a procesar otra tarea antes de que la primera termine. Esto puede cambiar el estado interno del actor inesperadamente entre el “antes” y el “después” delawait.
🧩 Nivel 21: Preguntas Trampa de Código (“Output Prediction”)
El entrevistador te pone este código en la pizarra. ¿Qué respondes?
- El misterio del Dispatch en Protocolos:
protocol A { func a() }
extension A { func a() { print("A") } }
struct B: A { func a() { print("B") } }
let b = B()
let a: A = b
b.a() // ¿Qué imprime?
a.a() // ¿Qué imprime?Respuesta: Imprime “B” y “B”. Como a() está definido en el requisito del protocolo, usa despacho dinámico (Witness Table) y encuentra la implementación de B.
El misterio de la Extensión Oculta:
protocol A { }
extension A { func a() { print("A") } } // No está en la definición del protocolo
struct B: A { func a() { print("B") } }
let a: A = B()
a.a()Respuesta: Imprime “A”. Como a() no está en la definición original del protocolo protocol A {}, se usa despacho estático. La variable a es de tipo A, así que usa la extensión de A, ignorando la de B.
Arrays y Closures:
var array = [1, 2, 3]
let closure = { print(array) }
array.append(4)
closure()Respuesta: Imprime [1, 2, 3]. Los Arrays son tipos de valor y el closure captura una copia del array en el momento de la creación del closure (capture list implícita de value types). Nota: Si array fuera una Clase, imprimiría 1, 2, 3, 4.
Defer Stack:
func test() {
defer { print("1") }
defer { print("2") }
print("3")
}- Respuesta: “3”, “2”, “1”. Los
deferse ejecutan en orden inverso (como una pila/stack) al salir del ámbito. - Lazy var y concurrencia: ¿Es seguro acceder a una propiedad
lazy vardesde múltiples hilos a la vez? Respuesta:No.lazy varno es thread-safe. Si dos hilos acceden a la vez por primera vez, el inicializador podría ejecutarse dos veces o causar un crash.
📐 Nivel 22: Patrones de Diseño en Swift
- ¿Qué es el patrón “Delegate”? Un patrón donde un objeto delega responsabilidad o notificación a otro. En Swift se usa con protocolos
weak var delegate: DelegateProtocol?para evitar ciclos de retención. - ¿Cómo implementas el patrón “Observer” en Swift puro? Usando
NotificationCenter, KVO, o más modernamente,@Publishedcon Combine/SwiftUI. - ¿Qué es “Dependency Injection” y por qué es vital? Pasar las dependencias a un objeto (generalmente en el
init) en lugar de que el objeto las cree. Vital para poder hacer Unit Testing con Mocks. - ¿Qué es el patrón “Builder”? Útil para crear objetos complejos paso a paso. En Swift, se ve a menudo de forma funcional (ej. configuradores de URLRequest).
- ¿Qué es el patrón “Coordinator”? (Muy usado en iOS) Extrae la lógica de navegación de los ViewControllers, facilitando el flujo y la reutilización de pantallas.
🏛 Nivel 23: Estructuras de Datos y Algoritmos (Contexto Swift)
- ¿Cuál es la complejidad de
array.insert(element, at: 0)? O(n), porque tiene que desplazar todos los elementos restantes una posición. - ¿Cuál es la complejidad de acceder a un valor en un Diccionario? O(1) en promedio.
- ¿Cómo funciona internamente el
Dictionaryen Swift? Usa “Linear Probing” (Sondeo lineal) y tablas hash abiertas. Requiere que las claves seanHashable. - ¿Qué es
ContiguousArray? Una versión especializada de Array que siempre almacena sus elementos de forma contigua en memoria. Es más eficiente queArrayestándar si almacenas clases o si no necesitas el bridging conNSArrayde Objective-C. - ¿Qué son los
Collectionprotocols?Sequence->Collection->BidirectionalCollection->RandomAccessCollection. Saber cuál usar es clave para crear tus propias estructuras de datos.
🧪 Nivel 24: Testing
- ¿Diferencia entre
setUpysetUpWithErroren XCTest?setUpWithErrorpermite lanzar errores (throws). Si falla, el test se marca como fallido limpiamente sin crashear. - ¿Qué es un “Mock” vs un “Stub”?
- Stub: Objeto falso que devuelve datos predefinidos (para que el test corra).
- Mock: Objeto falso que además verifica comportamiento (ej. “¿se llamó a este método exactamente 1 vez?”).
- ¿Cómo testeas código asíncrono en XCTest antiguo vs nuevo? Antiguo:
XCTestExpectationywait. Nuevo: Marcar la función de test comoasyncy usarawait.
🏁 Nivel 25: Miscelánea Experta
- ¿Qué es
Neveren Swift? Un tipo que indica que una función nunca retorna (ej.fatalError()o una función que crashea intencionalmente). - ¿Qué es
Voidrealmente? Es un typealias para una tupla vacía(). - ¿Qué es la reflexión (
Mirror) en Swift? Permite inspeccionar la estructura de un tipo en tiempo de ejecución (listar propiedades, tipos). Es limitado y lento comparado con otros lenguajes, pero útil para logging o serialización personalizada. - ¿Qué es el atributo
@discardableResult? Silencia el warning del compilador si llamas a una función que devuelve algo pero ignoras el resultado. - ¿Qué es el atributo
@available? Permite marcar código que solo debe ejecutarse en ciertas versiones de iOS/macOS o que está deprecado. - ¿Qué son los “KeyPaths” (
\Person.name)? Referencias seguras a una propiedad de un tipo, no a su valor. Permiten metaprogramación y APIs dinámicas elegantes. - ¿Qué es
@dynamicMemberLookup? Permite acceder a propiedades de un tipo usando sintaxis de punto (a.b) incluso si esas propiedades no existen en tiempo de compilación, resolviéndolas dinámicamente (útil para envolver JSON o Python). - ¿Qué es
@propertyWrapper? El mecanismo detrás de@State,@Published, etc. Te permite encapsular la lógica de almacenamiento de una propiedad en un tipo reutilizable. - ¿Cómo evitas la explosión de genéricos en el binario? Usando tipos existenciales (
any) donde el rendimiento estático no sea crítico, o usando@_specializecon cuidado. - ¿Qué es “ABI Stability”? Lograda en Swift 5.0. Significa que el runtime de Swift está integrado en el SO (iOS) y las apps no necesitan incluir las librerías de Swift dentro del binario, reduciendo el tamaño de la app y permitiendo compatibilidad binaria entre versiones.










