DEV Community

GoyesDev
GoyesDev

Posted on

[SC] Control del dominio de aislamiento por defecto en Swift 6.2

Comprensión durante la lectura

¿Qué significa exactamente "dominio de aislamiento por defecto" y por qué importa en Swift Concurrency?

Los tipos de datos (funciones y propiedades globales) en Swift 6.2 viven en algún tipo de aislamiento, bien sea nonisolated o un actor específico.

Como la mayoría de aplicaciones comienzan en el hilo principal y solo cambian de hilo si se introduce concurrencia explícitamente (lo que implica que la mayoría de tipos de datos vivirían en el mismo dominio de aislamiento MainActor), hay una funcionalidad opcional en Xcode 26 que permite marcar todos los tipos de datos dentro de un dominio de aislamiento por defecto. Este dominio de aislamiento puede ser MainActor (anteriormente era nonisolated por defecto).

Esta funcionalidad es importante porque, antes de que existiera, aparecía un montón de advertencias en todos los tipos de datos debido a que se asumía que todas eran nonisolated, pese a que de alguna manera estaban relacionadas con tipos de datos de MainActor. Silenciar una advertencia por un lado, podía levantar otra por otro lado.

¿Por qué tantos desarrolladores terminaban añadiendo @MainActor en todas partes?

La aplicación de iOS podía iniciar en @MainActor y no cambiar de hilo, sino hasta ejecutar alguna tarea específica.

El compilador no podía asumir que todas las clases no marcadas con @MainActor vivían dentro del dominio de MainActor, incluso aunque el desarrollador supiera que así ocurría, y que no había ningún riesgo de introducir una carrera de datos. Por esta razón, el desarrollador tenía que marcar todas las clases con @MainActor. Ahora, todas traen @MainActor implícito y, en caso de no querer este dominio de aislamiento, se tiene que cambiar manualmente.

¿Qué diferencia hay entre nonisolated y @MainActor como dominio por defecto?

nonisolated por defecto, indica que el código no está aislado en ningún dominio de aislamiento específico, por lo que el compilador no puede asegurar la ausencia de carreras de datos. ATENCIÓN: Esto no significa que HABRÁ una carrera de datos - Puede no haberla. Solo quiere decir que no se puede asegurar que no la haya.

@MainActor por defecto, indica que todo el código está aislado en MainActor, a no ser que se indique lo contrario. Esto asegura que no haya carreras de datos entre los llamados.

¿Cómo se configura el dominio de aislamiento por defecto en un proyecto Xcode y en un paquete Swift?

En un proyecto de Xcode hay que cambiar "default actor isolation".

En el caso del paquete de Swift, se puede aplicar el setting SwiftSetting.defaultIsolation(_:_:), teniendo en cuenta que puede recibir como aislamiento MainActor.self o nil.

Tomar como referencia el siguiente código para configurar un paquete de Swift:

import PackageDescription

let package = Package(
  name: "MyPackage",
  targets: [
    .target(
      name: "MyTarget",
      swiftSettings: [
        .define("ENABLE_FEATURE_A"),
        .define("DEBUG_MODE", .when(configuration: .debug)),
        .enableUpcomingFeature("ExistentialAny")
      ]
    ),
    .testTarget(
      name: "MyTargetTests",
      dependencies: ["MyTarget"]
    ),
  ]
)
Enter fullscreen mode Exit fullscreen mode

¿Por qué tiene sentido que la mayoría del código de una app corra en el hilo principal por defecto?

La mayoría de código de una app inicia en el hilo principal y permanece allí hasta que explícitamente se introduce concurrencia. En este escenario, si todo corre secuencial, no hay carreras de datos, así que asumir que el código está en nonisolated provoca falsas alarmas. En lugar de eso, es mejor asumir por defecto que el código corre en el hilo principal.

Según el ejemplo de código del artículo, ¿qué ocurre con la inferencia de aislamiento en class, structs y actor cuando se usa @MainActor como valor por defecto?

Al usar @MainActor como valor por defecto, class y struct (junto con atributos y métodos), vivirán enMainActor. Al crear unactor, sus métodosinitydeinitseránnonisolated` y el resto estarán aislados dentro del dominio de aislamiento definido por él mismo.

En el caso de que class y struct conformen un protocolo, estos heredarán el dominio de aislamiento definido para el protocolo.


Recordar sin releer

¿Este cambio rompe proyectos existentes? ¿Por qué sí o por qué no?

No rompe proyectos existentes el cambio es opcional. Si no se aplica, entonces el código asume por defecto nonisolated.

¿El ajuste se aplica globalmente a todo el proyecto o hay que configurarlo módulo por módulo?

Hay que configurarlo por módulo.


Revisión y síntesis

¿Cuál es el impacto práctico de cambiar el dominio de aislamiento en la migración a Swift 6?

¿Qué riesgos menciona el equipo de Swift respecto a tener dialectos de lenguaje distintos según el módulo?


Bibliografía

Top comments (0)