How to determine where code runs in Swift Concurrency

Поділитися
Вставка
  • Опубліковано 27 гру 2024

КОМЕНТАРІ • 23

  • @chovuse
    @chovuse 9 місяців тому +1

    Your style of tutorial makes it more easier to understand Swift coding. Thanks a Lot !

  • @ВолодимирСахаревич
    @ВолодимирСахаревич 6 місяців тому

    Kudos to the author.
    First time I hear simple and elaborated explanation about threads which will be used to run task or specific method.

  • @FloWritesCode
    @FloWritesCode 10 місяців тому

    This is an interesting topic, thanks a ton for sharing!

  • @AkimboFennec
    @AkimboFennec 4 місяці тому

    Hey danni. I have a question for you. Let say in iOS 18, new Xcode 16, every view is already annotated with the @MainActor. Furthermore, let’s say I have a certain function, called func sortArray() async. Now, since this functino is inside a view, that is annotated with a main actor, but it is marked as async, it will block the main thread. I tested it in SwiftUI. Inside this sortArray() async, i have var array = Array(repeating: 2, count: 30_000_000); array.sort(). And let’s say that this function is triggered by a certain button press. As soon as i press this button, the UI totally freezes, and does not respond until the array sort operation finishes. However, as soon as i mark this async function as non isolated, then everything works fine, and the UI responds, while another thread is sorting this array. Why does this happen? You said int the video that marking a function as await does not freeze the UI. I don’t understand it conceptually

    • @DonnyWalsdev
      @DonnyWalsdev  4 місяці тому +1

      Hey! Thanks for your question.
      So the await itself isn't why your function blocked the main actor. It's because the thing you were awaiting itself runs on the main actor that your UI freezes. That's also why marking the function as nonisolated fixes your problem. Even though you're awaiting the nonisolated function from the main actor, the main actor can do other stuff (like keeping your UI responsive) while it waits for the nonisolated async function to come back.
      In other words, while the await does not block the main actor, the thing your waiting for might.

  • @alperenunal3975
    @alperenunal3975 10 місяців тому

    Btw what’s your xcode theme ? Looks very cool :)

    • @DonnyWalsdev
      @DonnyWalsdev  9 місяців тому +1

      It's "Material theme Ocean high contrast" in VS code

  • @bobdel
    @bobdel 8 місяців тому

    This video is very helpful. I am still confused by the body property. As I understand it, Body is annotated via a protocol to run on MainActor. Is this correct: a view such as the one in your example that does not have a @MainActor annotation, but the function is called from a task modifier inside the Body will run on the MainActor.

    • @DonnyWalsdev
      @DonnyWalsdev  8 місяців тому

      It's the opposite, unless the function definition itself has a @Mainactor annotation (or in other words, is isolated to the main actor) it doesn't matter where you call it from. The function itself decides where it runs and if it's not isolated to the main actor explicitly it will run in the background even if it was called from a main actor isolated spot

  • @pmatar
    @pmatar 10 місяців тому

    Great video, thanks for sharing! And what about the assigning of the result of async func to UI-related piece? How exactly it works and should we care about main thread the same way as with gcd?

    • @DonnyWalsdev
      @DonnyWalsdev  10 місяців тому

      Yes you should make sure you assign on the main actor. The easiest way is to make sure that the property you’re assigning too is main actor annotated. That way you’ll never forget because all access to the property will be isolated to the main actor.
      Alternatively you can use MainActor.run to run a piece of code on the main actor

    • @pmatar
      @pmatar 10 місяців тому

      @@DonnyWalsdev oh I see what you mean. Thank you for your response!

  • @alperenunal3975
    @alperenunal3975 10 місяців тому

    If we are using @observable macro on our viewmodel, should we use @mainactor at the same time ?

    • @DonnyWalsdev
      @DonnyWalsdev  10 місяців тому

      I would advice that you do on the view, SwiftUI views aren’t main actor isolated by default

    • @alperenunal3975
      @alperenunal3975 10 місяців тому

      @@DonnyWalsdev so we should mark View as a main actor ?

    • @DonnyWalsdev
      @DonnyWalsdev  9 місяців тому

      @@alperenunal3975IMO, yes that would be a good idea. It's honestly a little surprising to me that Apple doesn't enforce this

    • @alperenunal3975
      @alperenunal3975 9 місяців тому

      @@DonnyWalsdev oh, I got it. Thanks for explanation :)

  • @pmatar
    @pmatar 10 місяців тому

    private var imageUrl: String? {
    didSet {
    dowloadImage()
    }
    }
    func setImage(_ imageUrl: String?, placeholder: UIImage?) {
    self.image = placeholder
    self.imageUrl = imageUrl
    }
    private func dowloadImage() {
    guard let imageUrl else { return }
    Task { @MainActor in
    do {
    let loadedImage = try await ImageLoader.shared.downloadImage(from: imageUrl)
    if imageUrl == self.imageUrl {
    image = loadedImage
    }
    } catch {
    debugPrint(error)
    }
    }
    }
    That’s the example of what I mean

    • @DonnyWalsdev
      @DonnyWalsdev  10 місяців тому

      This would work perfectly fine. Your task is run on the main thread which means the assignment you do at the end is on the main actor

    • @pmatar
      @pmatar 10 місяців тому

      @@DonnyWalsdev but won’t the download will also happen on the main thread, instead of global/background?

    • @DonnyWalsdev
      @DonnyWalsdev  10 місяців тому

      @@pmatar no, because the download function itself most likely is defined non isolated. If not, you can be certain that URLSession’s networking is non isolated. So that code run on the global executor.
      While you await, the main thread is free to work on other stuff because an await doesn’t block; it frees the actor up for other work