View in English

  • Apple Developer
    • Get Started

    Explore Get Started

    • Overview
    • Learn
    • Apple Developer Program

    Stay Updated

    • Latest News
    • Hello Developer
    • Platforms

    Explore Platforms

    • Apple Platforms
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    Featured

    • Design
    • Distribution
    • Games
    • Accessories
    • Web
    • Home
    • CarPlay
    • Technologies

    Explore Technologies

    • Overview
    • Xcode
    • Swift
    • SwiftUI

    Featured

    • Accessibility
    • App Intents
    • Apple Intelligence
    • Games
    • Machine Learning & AI
    • Security
    • Xcode Cloud
    • Community

    Explore Community

    • Overview
    • Meet with Apple events
    • Community-driven events
    • Developer Forums
    • Open Source

    Featured

    • WWDC
    • Swift Student Challenge
    • Developer Stories
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Centers
    • Documentation

    Explore Documentation

    • Documentation Library
    • Technology Overviews
    • Sample Code
    • Human Interface Guidelines
    • Videos

    Release Notes

    • Featured Updates
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • Downloads

    Explore Downloads

    • All Downloads
    • Operating Systems
    • Applications
    • Design Resources

    Featured

    • Xcode
    • TestFlight
    • Fonts
    • SF Symbols
    • Icon Composer
    • Support

    Explore Support

    • Overview
    • Help Guides
    • Developer Forums
    • Feedback Assistant
    • Contact Us

    Featured

    • Account Help
    • App Review Guidelines
    • App Store Connect Help
    • Upcoming Requirements
    • Agreements and Guidelines
    • System Status
  • Quick Links

    • Events
    • News
    • Forums
    • Sample Code
    • Videos
 

Vidéos

Ouvrir le menu Fermer le menu
  • Collections
  • Toutes les vidéos
  • À propos

Plus de vidéos

  • À propos
  • Résumé
  • Code
  • Adoptez la concurrence avec Swift

    Rejoignez-nous pour découvrir les concepts fondamentaux de concurrence en Swift. La concurrence vous aide à améliorer la réactivité et les performances des apps, et Swift est conçu pour faciliter l'écriture sans erreur de code asynchrone et concurrent. Nous passerons en revue les étapes nécessaires pour faire évoluer une app d'un fonctionnement monothread à un fonctionnement concurrent. Nous vous aiderons également à déterminer comment et quand tirer le meilleur parti des fonctionnalités de concurrence en Swift, qu'il s'agisse de rendre votre code plus asynchrone, de le déplacer en arrière-plan ou de partager des données entre des tâches concurrentes.

    Chapitres

    • 0:00 - Introduction
    • 3:17 - Code monothread
    • 6:00 - Tâches asynchrones
    • 7:24 - Entrelacement
    • 10:22 - Présentation de la concurrence
    • 11:07 - Fonctions concurrentes
    • 13:10 - Code non isolé
    • 14:13 - Pool de threads concurrents
    • 14:58 - Partage des données
    • 15:49 - Types de valeur
    • 17:16 - Types isolés par un acteur
    • 18:30 - Classes
    • 23:18 - Acteurs
    • 26:12 - Conclusion

    Ressources

    • Swift Migration Guide
    • The Swift Programming Language: Concurrency
      • Vidéo HD
      • Vidéo SD

    Vidéos connexes

    WWDC25

    • Code-along : Améliorez une app avec la concurrence Swift

    WWDC23

    • Beyond the basics of structured concurrency
  • Rechercher dans cette vidéo…
    • 3:20 - Single-threaded program

      var greeting = "Hello, World!"
      
      func readArguments() { }
      
      func greet() {
        print(greeting)
      }
      
      readArguments()
      greet()
    • 4:13 - Data types in a the app

      struct Image {
      }
      
      final class ImageModel {
        var imageCache: [URL: Image] = [:]
      }
      
      final class Library {
        static let shared: Library = Library()
      }
    • 4:57 - Load and display a local image

      import Foundation
      
      class Image {
      }
      
      final class View {
        func displayImage(_ image: Image) {
        }
      }
      
      final class ImageModel {
        var imageCache: [URL: Image] = [:]
        let view = View()
      
        func fetchAndDisplayImage(url: URL) throws {
          let data = try Data(contentsOf: url)
          let image = decodeImage(data)
          view.displayImage(image)
        }
      
        func decodeImage(_ data: Data) -> Image {
          Image()
        }
      }
      
      final class Library {
        static let shared: Library = Library()
      }
    • 5:36 - Fetch and display an image over the network

      import Foundation
      
      struct Image {
      }
      
      final class View {
        func displayImage(_ image: Image) {
        }
      }
      
      final class ImageModel {
        var imageCache: [URL: Image] = [:]
        let view = View()
      
        func fetchAndDisplayImage(url: URL) throws {
          let (data, _) = try URLSession.shared.data(from: url)
          let image = decodeImage(data)
          view.displayImage(image)
        }
      
        func decodeImage(_ data: Data) -> Image {
          Image()
        }
      }
      
      final class Library {
        static let shared: Library = Library()
      }
    • 6:10 - Fetch and display image over the network asynchronously

      import Foundation
      
      class Image {
      }
      
      final class View {
        func displayImage(_ image: Image) {
        }
      }
      
      final class ImageModel {
        var imageCache: [URL: Image] = [:]
        let view = View()
      
        func fetchAndDisplayImage(url: URL) async throws {
          let (data, _) = try await URLSession.shared.data(from: url)
          let image = decodeImage(data)
          view.displayImage(image)
        }
      
        func decodeImage(_ data: Data) -> Image {
          Image()
        }
      }
      
      final class Library {
        static let shared: Library = Library()
      }
    • 7:31 - Creating a task to perform asynchronous work

      import Foundation
      
      class Image {
      }
      
      final class View {
        func displayImage(_ image: Image) {
        }
      }
      
      final class ImageModel {
        var imageCache: [URL: Image] = [:]
        let view = View()
        var url: URL = URL("https://swift.org")!
      
        func onTapEvent() {
          Task {
            do {
      	try await fetchAndDisplayImage(url: url)
            } catch let error {
              displayError(error)
            }
          }
        }
      
        func displayError(_ error: any Error) {
        }
      
        func fetchAndDisplayImage(url: URL) async throws {
        }
      }
      
      final class Library {
        static let shared: Library = Library()
      }
    • 9:15 - Ordered operations in a task

      import Foundation
      
      class Image {
        func applyImageEffect() async { }
      }
      
      final class ImageModel {
        func displayImage(_ image: Image) {
        }
      
        func loadImage() async -> Image {
          Image()
        }
        
        func onButtonTap() {
          Task {
            let image = await loadImage()
            await image.applyImageEffect()
            displayImage(image)
          }
        }
      }
    • 9:38 - Fetch and display image over the network asynchronously

      import Foundation
      
      class Image {
      }
      
      final class View {
        func displayImage(_ image: Image) {
        }
      }
      
      final class ImageModel {
        var imageCache: [URL: Image] = [:]
        let view = View()
      
        func fetchAndDisplayImage(url: URL) async throws {
          let (data, _) = try await URLSession.shared.data(from: url)
          let image = decodeImage(data)
          view.displayImage(image)
        }
      
        func decodeImage(_ data: Data) -> Image {
          Image()
        }
      }
    • 10:40 - Fetch and display image over the network asynchronously

      import Foundation
      
      class Image {
      }
      
      final class View {
        func displayImage(_ image: Image) {
        }
      }
      
      final class ImageModel {
        var imageCache: [URL: Image] = [:]
        let view = View()
      
        func fetchAndDisplayImage(url: URL) async throws {
          let (data, _) = try await URLSession.shared.data(from: url)
          let image = decodeImage(data, at: url)
          view.displayImage(image)
        }
      
        func decodeImage(_ data: Data, at url: URL) -> Image {
          Image()
        }
      }
    • 11:11 - Fetch over network asynchronously and decode concurrently

      import Foundation
      
      class Image {
      }
      
      final class View {
        func displayImage(_ image: Image) {
        }
      }
      
      final class ImageModel {
        var imageCache: [URL: Image] = [:]
        let view = View()
      
        func fetchAndDisplayImage(url: URL) async throws {
          let (data, _) = try await URLSession.shared.data(from: url)
          let image = await decodeImage(data, at: url)
          view.displayImage(image)
        }
      
        @concurrent
        func decodeImage(_ data: Data, at url: URL) async -> Image {
          Image()
        }
      }
    • 11:30 - Implementation of decodeImage

      final class View {
        func displayImage(_ image: Image) {
        }
      }
      
      final class ImageModel {
        var cachedImage: [URL: Image] = [:]
        let view = View()
      
        func fetchAndDisplayImage(url: URL) async throws {
          let (data, _) = try await URLSession.shared.data(from: url)
          let image = await decodeImage(data, at: url)
          view.displayImage(image)
        }
      
        @concurrent
        func decodeImage(_ data: Data, at url: URL) async -> Image {
          if let image = cachedImage[url] {
            return image
          }
      
          // decode image
          let image = Image()
          cachedImage[url] = image
          return image
        }
      }
    • 12:37 - Correct implementation of fetchAndDisplayImage with caching and concurrency

      import Foundation
      
      class Image {
      }
      
      final class View {
        func displayImage(_ image: Image) {
        }
      }
      
      final class ImageModel {
        var cachedImage: [URL: Image] = [:]
        let view = View()
      
        func fetchAndDisplayImage(url: URL) async throws {
          if let image = cachedImage[url] {
            view.displayImage(image)
            return
          }
      
          let (data, _) = try await URLSession.shared.data(from: url)
          let image = await decodeImage(data)
          view.displayImage(image)
        }
      
        @concurrent
        func decodeImage(_ data: Data) async -> Image {
          // decode image
          Image()
        }
      }
    • 13:30 - JSONDecoder API should be non isolated

      // Foundation
      import Foundation
      
      nonisolated
      public class JSONDecoder {
        public func decode<T: Decodable>(_ type: T.Type, from data: Data) -> T {
          fatalError("not implemented")
        }
      }
    • 15:18 - Fetch over network asynchronously and decode concurrently

      import Foundation
      
      class Image {
      }
      
      final class View {
        func displayImage(_ image: Image) {
        }
      }
      
      final class ImageModel {
        var imageCache: [URL: Image] = [:]
        let view = View()
      
        func fetchAndDisplayImage(url: URL) async throws {
          let (data, _) = try await URLSession.shared.data(from: url)
          let image = await decodeImage(data, at: url)
          view.displayImage(image)
        }
      
        @concurrent
        func decodeImage(_ data: Data, at url: URL) async -> Image {
          Image()
        }
      }
    • 16:30 - Example of value types

      // Value types are common in Swift
      import Foundation
      
      struct Post {
        var author: String
        var title: String
        var date: Date
        var categories: [String]
      }
    • 16:56 - Sendable value types

      import Foundation
      
      // Value types are Sendable
      extension URL: Sendable {}
      
      // Collections of Sendable elements
      extension Array: Sendable where Element: Sendable {}
      
      // Structs and enums with Sendable storage
      struct ImageRequest: Sendable {
        var url: URL
      }
      
      // Main-actor types are implicitly Sendable
      @MainActor class ImageModel {}
    • 17:25 - Fetch over network asynchronously and decode concurrently

      import Foundation
      
      class Image {
      }
      
      final class View {
        func displayImage(_ image: Image) {
        }
      }
      
      final class ImageModel {
        var imageCache: [URL: Image] = [:]
        let view = View()
      
        func fetchAndDisplayImage(url: URL) async throws {
          let (data, _) = try await URLSession.shared.data(from: url)
          let image = await self.decodeImage(data, at: url)
          view.displayImage(image)
        }
      
        @concurrent
        func decodeImage(_ data: Data, at url: URL) async -> Image {
          Image()
        }
      }
    • 18:34 - MyImage class with reference semantics

      import Foundation
      
      struct Color { }
      
      nonisolated class MyImage {
        var width: Int
        var height: Int
        var pixels: [Color]
        var url: URL
      
        init() {
          width = 100
          height = 100
          pixels = []
          url = URL("https://swift.org")!
        }
      
        func scale(by factor: Double) {
        }
      }
      
      let image = MyImage()
      let otherImage = image // refers to the same object as 'image'
      image.scale(by: 0.5)   // also changes otherImage!
    • 19:19 - Concurrently scaling while displaying an image is a data race

      import Foundation
      
      struct Color { }
      
      nonisolated class MyImage {
        var width: Int
        var height: Int
        var pixels: [Color]
        var url: URL
      
        init() {
          width = 100
          height = 100
          pixels = []
          url = URL("https://swift.org")!
        }
      
        func scaleImage(by factor: Double) {
        }
      }
      
      final class View {
        func displayImage(_ image: MyImage) {
        }
      }
      
      final class ImageModel {
        var cachedImage: [URL: MyImage] = [:]
        let view = View()
      
        // Slide content start
        func scaleAndDisplay(imageName: String) {
          let image = loadImage(imageName)
          Task { @concurrent in
            image.scaleImage(by: 0.5)
          }
      
          view.displayImage(image)
        }
        // Slide content end
      
        func loadImage(_ imageName: String) -> MyImage {
          // decode image
          return MyImage()
        }
      }
    • 20:38 - Scaling and then displaying an image eliminates the data race

      import Foundation
      
      struct Color { }
      
      nonisolated class MyImage {
        var width: Int
        var height: Int
        var pixels: [Color]
        var url: URL
      
        init() {
          width = 100
          height = 100
          pixels = []
          url = URL("https://swift.org")!
        }
      
        func scaleImage(by factor: Double) {
        }
      }
      
      final class View {
        func displayImage(_ image: MyImage) {
        }
      }
      
      final class ImageModel {
        var cachedImage: [URL: MyImage] = [:]
        let view = View()
      
        func scaleAndDisplay(imageName: String) {
          Task { @concurrent in
            let image = loadImage(imageName)
            image.scaleImage(by: 0.5)
            await view.displayImage(image)
          }
        }
      
        nonisolated
        func loadImage(_ imageName: String) -> MyImage {
          // decode image
          return MyImage()
        }
      }
    • 20:54 - Scaling and then displaying an image within a concurrent asynchronous function

      import Foundation
      
      struct Color { }
      
      nonisolated class MyImage {
        var width: Int
        var height: Int
        var pixels: [Color]
        var url: URL
      
        init() {
          width = 100
          height = 100
          pixels = []
          url = URL("https://swift.org")!
        }
      
        func scaleImage(by factor: Double) {
        }
      }
      
      final class View {
        func displayImage(_ image: MyImage) {
        }
      }
      
      final class ImageModel {
        var cachedImage: [URL: MyImage] = [:]
        let view = View()
      
        @concurrent
        func scaleAndDisplay(imageName: String) async {
          let image = loadImage(imageName)
          image.scaleImage(by: 0.5)
          await view.displayImage(image)
        }
      
        nonisolated
        func loadImage(_ imageName: String) -> MyImage {
          // decode image
          return MyImage()
        }
      }
    • 21:11 - Scaling, then displaying and concurrently modifying an image is a data race

      import Foundation
      
      struct Color { }
      
      nonisolated class MyImage {
        var width: Int
        var height: Int
        var pixels: [Color]
        var url: URL
      
        init() {
          width = 100
          height = 100
          pixels = []
          url = URL("https://swift.org")!
        }
      
        func scaleImage(by factor: Double) {
        }
      
        func applyAnotherEffect() {
        }
      }
      
      final class View {
        func displayImage(_ image: MyImage) {
        }
      }
      
      final class ImageModel {
        var cachedImage: [URL: MyImage] = [:]
        let view = View()
      
        // Slide content start
        @concurrent
        func scaleAndDisplay(imageName: String) async {
          let image = loadImage(imageName)
          image.scaleImage(by: 0.5)
          await view.displayImage(image)
          image.applyAnotherEffect()
        }
        // Slide content end
      
        nonisolated
        func loadImage(_ imageName: String) -> MyImage {
          // decode image
          return MyImage()
        }
      }
    • 21:20 - Applying image transforms before sending to the main actor

      import Foundation
      
      struct Color { }
      
      nonisolated class MyImage {
        var width: Int
        var height: Int
        var pixels: [Color]
        var url: URL
      
        init() {
          width = 100
          height = 100
          pixels = []
          url = URL("https://swift.org")!
        }
      
        func scaleImage(by factor: Double) {
        }
      
        func applyAnotherEffect() {
        }
      }
      
      final class View {
        func displayImage(_ image: MyImage) {
        }
      }
      
      final class ImageModel {
        var cachedImage: [URL: MyImage] = [:]
        let view = View()
      
        // Slide content start
        @concurrent
        func scaleAndDisplay(imageName: String) async {
          let image = loadImage(imageName)
          image.scaleImage(by: 0.5)
          image.applyAnotherEffect()
          await view.displayImage(image)
        }
        // Slide content end
      
        nonisolated
        func loadImage(_ imageName: String) -> MyImage {
          // decode image
          return MyImage()
        }
      }
    • 22:06 - Closures create shared state

      import Foundation
      
      struct Color { }
      
      nonisolated class MyImage {
        var width: Int
        var height: Int
        var pixels: [Color]
        var url: URL
      
        init() {
          width = 100
          height = 100
          pixels = []
          url = URL("https://swift.org")!
        }
      
        func scale(by factor: Double) {
        }
      
        func applyAnotherEffect() {
        }
      }
      
      final class View {
        func displayImage(_ image: MyImage) {
        }
      }
      
      final class ImageModel {
        var cachedImage: [URL: MyImage] = [:]
        let view = View()
      
        // Slide content start
        @concurrent
        func scaleAndDisplay(imageName: String) async throws {
          let image = loadImage(imageName)
          try await perform(afterDelay: 0.1) {
            image.scale(by: 0.5)
          }
          await view.displayImage(image)
        }
      
        nonisolated
        func perform(afterDelay delay: Double, body: () -> Void) async throws {
          try await Task.sleep(for: .seconds(delay))
          body()
        }
        // Slide content end
        
        nonisolated
        func loadImage(_ imageName: String) -> MyImage {
          // decode image
          return MyImage()
        }
      }pet.
    • 23:47 - Network manager class

      import Foundation
      
      nonisolated class MyImage { }
      
      struct Connection {
        func data(from url: URL) async throws -> Data { Data() }
      }
      
      final class NetworkManager {
        var openConnections: [URL: Connection] = [:]
      
        func openConnection(for url: URL) async -> Connection {
          if let connection = openConnections[url] {
            return connection
          }
      
          let connection = Connection()
          openConnections[url] = connection
          return connection
        }
      
        func closeConnection(_ connection: Connection, for url: URL) async {
          openConnections.removeValue(forKey: url)
        }
      
      }
      
      final class View {
        func displayImage(_ image: MyImage) {
        }
      }
      
      final class ImageModel {
        var cachedImage: [URL: MyImage] = [:]
        let view = View()
        let networkManager: NetworkManager = NetworkManager()
      
        func fetchAndDisplayImage(url: URL) async throws {
          if let image = cachedImage[url] {
            view.displayImage(image)
            return
          }
      
          let connection = await networkManager.openConnection(for: url)
          let data = try await connection.data(from: url)
          await networkManager.closeConnection(connection, for: url)
      
          let image = await decodeImage(data)
          view.displayImage(image)
        }
      
        @concurrent
        func decodeImage(_ data: Data) async -> MyImage {
          // decode image
          return MyImage()
        }
      }
    • 25:10 - Network manager as an actor

      import Foundation
      
      nonisolated class MyImage { }
      
      struct Connection {
        func data(from url: URL) async throws -> Data { Data() }
      }
      
      actor NetworkManager {
        var openConnections: [URL: Connection] = [:]
      
        func openConnection(for url: URL) async -> Connection {
          if let connection = openConnections[url] {
            return connection
          }
      
          let connection = Connection()
          openConnections[url] = connection
          return connection
        }
      
        func closeConnection(_ connection: Connection, for url: URL) async {
          openConnections.removeValue(forKey: url)
        }
      
      }
      
      final class View {
        func displayImage(_ image: MyImage) {
        }
      }
      
      final class ImageModel {
        var cachedImage: [URL: MyImage] = [:]
        let view = View()
        let networkManager: NetworkManager = NetworkManager()
      
        func fetchAndDisplayImage(url: URL) async throws {
          if let image = cachedImage[url] {
            view.displayImage(image)
            return
          }
      
          let connection = await networkManager.openConnection(for: url)
          let data = try await connection.data(from: url)
          await networkManager.closeConnection(connection, for: url)
      
          let image = await decodeImage(data)
          view.displayImage(image)
        }
      
        @concurrent
        func decodeImage(_ data: Data) async -> MyImage {
          // decode image
          return MyImage()
        }
      }
    • 0:00 - Introduction
    • La simultanéité Swift permet aux apps d’exécuter plusieurs tâches à la fois, améliorant la réactivité et déchargeant les calculs en arrière-plan. Le modèle de simultanéité Swift facilite l’écriture correcte du code concurrent en rendant la gestion de la concurrence claire, en identifiant les données partagées entre tâches, et en détectant les conflits de données lors de la compilation. Les apps commencent par exécuter tout le code sur le thread principal. À mesure que la complexité augmente, on peut introduire des tâches asynchrones pour les opérations longues comme l’accès réseau. Les threads en arrière-plan sont utilisés pour les tâches plus lourdes en calcul. Swift fournit des outils tels que des acteurs et des tâches pour gérer ces opérations simultanées.

    • 3:17 - Code monothread
    • En Swift, le code monothread s’exécute sur le thread principal, isolé de l’acteur principal. Il n’y a pas de simultanéité sur l’acteur principal, car un seul thread peut l’exécuter. Les données ou le code peuvent être placés sur l’acteur principal via la notation @MainActor. Swift veille à ce que le code de l’acteur principal ne s’exécute que sur le thread principal et que ses données ne soient accessibles qu’à partir de là. On dit alors que ce code est isolé de l’acteur principal. Par défaut, Swift protège le code du thread principal avec l’acteur principal, ce qui permet d’accéder librement à l’état partagé. La protection du code avec l’acteur principal est pilotée par défaut par un paramètre de build. Utilisez-le principalement pour le module principal de l’app et les modules liés à I’UI.

    • 6:00 - Tâches asynchrones
    • La simultanéité Swift utilise async et await pour rendre les fonctions non bloquantes, ce qui permet d’exécuter d’autres tâches en attendant des données. Cela évite les blocages et améliore la réactivité de l’UI en séparant les fonctions avant et après l’évènement attendu.

    • 7:24 - Entrelacement
    • Les fonctions asynchrones s’exécutent dans une tâche, indépendamment des autres. Un seul thread peut alterner entre des tâches prêtes à s’exécuter grâce à l’entrelacement. Cela améliore les performances en évitant les temps morts et en optimisant l’utilisation des ressources. Les tâches asynchrones sont efficaces pour exécuter de nombreuses opérations indépendantes en même temps. Pour exécuter des tâches dans un ordre précis, utilisez une seule tâche. Des tâches asynchrones sur un seul thread suffisent souvent. Si le thread principal est surchargé, des outils comme Instruments permettent d’identifier les goulots d’étranglement à optimiser avant de recourir à la simultanéité.

    • 10:22 - Présentation de la concurrence
    • La simultanéité permet d’exécuter du code en arrière-plan en parallèle du thread principal, en tirant parti des cœurs CPU pour accélérer le travail. Pour améliorer les performances, l’exemple utilise la simultanéité pour exécuter du code en arrière-plan et libérer le thread principal.

    • 11:07 - Fonctions concurrentes
    • En appliquant l’attribut @concurrent, Swift est invité à exécuter une fonction en arrière-plan. Le compilateur Swift signale les accès aux données via l’acteur principal pour introduire la simultanéité en toute sécurité. Une bonne pratique consiste à déplacer le code de l’acteur principal dans un appelant qui s’exécute toujours sur le thread principal.

    • 13:10 - Code non isolé
    • Une fonction @concurrent se déconnectera toujours d’un acteur pour s’exécuter. Le mot-clé nonisolated permet aux clients de choisir où exécuter le code : sur le thread principal ou en arrière-plan. Pour les bibliothèques à usage général, mieux vaut proposer une API nonisolated et laisser le client décider de décharger le travail ou non. Pour aller plus loin, regardez « Beyond the basics of structured concurrency » de la WWDC23.

    • 14:13 - Pool de threads concurrents
    • Lorsque le travail est délégué en arrière-plan, le système le planifie sur des threads d’un pool concurrent. Les petits appareils ont moins de threads dans le pool, tandis que les systèmes plus puissants en ont davantage. Les tâches sont affectées aux threads disponibles, qui peuvent varier en fonction des pauses et des reprises des tâches, pour optimiser les ressources.

    • 14:58 - Partage des données
    • Avec la simultanéité, partager des données entre threads peut provoquer des bugs à l’exécution si l’état mutable est mal géré. Swift limite ce risque grâce à des vérifications à la compilation, ce qui aide les développeurs à écrire du code concurrent en toute confiance.

    • 15:49 - Types de valeur
    • L’utilisation des types valeur offre un réel avantage avec les tâches simultanées. Quand un type valeur est copié en arrière-plan, il devient indépendant : les changements sur le thread principal n’ont aucun impact sur lui. Cette indépendance permet de partager les types valeur en toute sécurité entre les threads. Les types valeur conformes au protocole Sendable peuvent toujours être partagés en toute sécurité. Les types liés à l’acteur principal sont implicitement Sendable.

    • 17:16 - Types isolés par un acteur
    • Les acteurs Swift protègent l’état non Sendable en garantissant un accès à une seule tâche. Lorsque des valeurs circulent entre acteurs, le compilateur Swift en vérifie la sécurité.

    • 18:30 - Classes
    • En Swift, les classes sont des types référence : toute modification via une variable est visible par toutes les autres qui pointent vers le même objet. Quand plusieurs threads modifient un objet non-Sendable en même temps, cela peut provoquer des conflits, des bugs ou des pannes. Le système de simultanéité de Swift empêche cela à la compilation en imposant que seuls les types Sendable soient partagés entre acteurs et tâches. Pour éviter les conflits d’accès, il est crucial de ne pas partager d’objets mutables simultanément. Terminez les modifications sur un objet avant de l’envoyer à une autre tâche ou acteur pour affichage ou traitement. Si un objet doit être modifié sur un thread d’arrière-plan, rendez-le nonisolated, sans le rendre Sendable. Les fermetures avec état partagé peuvent être sûres, tant qu’elles ne sont pas appelées simultanément.

    • 23:18 - Acteurs
    • À mesure que l’app grandit, l’acteur principal gère beaucoup d’états, entrainant des changements fréquents de contexte. L’introduction d’acteurs peut atténuer cela. Les acteurs isolent leurs données, accessibles par un seul thread à la fois, évitant ainsi les conflits. En déplaçant l’état vers des acteurs dédiés, plus de code peut s’exécuter en parallèle sur des threads d’arrière-plan. Cela libère le thread principal pour maintenir la réactivité. Les classes liées à l’UI ou au modèle doivent rester sur l’acteur principal ou être non-Sendable.

    • 26:12 - Conclusion
    • Les apps commencent souvent en monothread, puis évoluent vers l’asynchrone, la concurrence et les acteurs pour gagner en performance. La simultanéité Swift facilite cette transition en facilitant le déplacement du code hors du thread principal et en améliorant la réactivité. Les outils de profilage comme Instruments aident à identifier quand et quel code doit être retiré du thread principal. Utilisez les réglages de build recommandés pour faciliter l’ajout de la simultanéité, et activez l’option Approachable Concurrency pour profiter de nouvelles fonctionnalités qui en simplifient l’usage.

Developer Footer

  • Vidéos
  • WWDC25
  • Adoptez la concurrence avec Swift
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • Apple Intelligence
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Downloads
    • Sample Code
    • Videos
    Open Menu Close Menu
    • Help Guides & Articles
    • Contact Us
    • Forums
    • Feedback & Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • Mini Apps Partner Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Read the latest news.
    Get the Apple Developer app.
    Copyright © 2026 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines