Swift Concurrency: async/await and Actors Essentials Quiz Quiz

Dive into the fundamentals of Swift's concurrency model, focusing on async/await syntax and actor types. This quiz helps you reinforce your understanding of structured concurrency and actor-based isolation for safer, more efficient code execution.

  1. Async Functions

    Which keyword must you use to mark a function as asynchronous and allow it to be awaited in Swift?

    1. asynk
    2. async
    3. asyncFunc
    4. await

    Explanation: The correct keyword for marking a function as asynchronous in Swift is 'async'. The keyword 'await' is used when calling an asynchronous function, not declaring it. 'asyncFunc' and 'asynk' are incorrect and are not recognized Swift keywords. Specifying 'async' tells the compiler and readers that the function can suspend and await completion.

  2. Calling Asynchronous Code

    Which keyword do you use when calling an async function to signal that the operation may suspend execution?

    1. async
    2. suspend
    3. await
    4. wait

    Explanation: 'await' is used when calling asynchronous functions to indicate that the function may pause the current task while waiting for completion. 'async' is used to mark the function itself as asynchronous, not to call it. 'suspend' and 'wait' are not valid keywords in Swift concurrency for this purpose.

  3. Thread Safety with Actors

    How do actors in Swift help prevent data races in concurrent code?

    1. They disable concurrency for the enclosed data.
    2. They automatically lock all variables in a project.
    3. They isolate mutable state and serialize access to their properties.
    4. They run on a dedicated thread continually.

    Explanation: Actors in Swift provide a form of data isolation by serializing access to their mutable state, preventing multiple concurrent accesses. They do not run on a dedicated thread but use the system's concurrency scheduler. Actors do not globally lock all variables nor do they disable concurrency altogether. Their primary role is to safely manage mutable data in concurrent scenarios.

  4. Calling Actor Methods

    What is required when calling a method on an instance of a Swift actor from outside of that actor?

    1. Nothing special is needed; call it directly without 'await'.
    2. Use the 'async' keyword right before the method name.
    3. Wrap the call with 'Task' only.
    4. You must use the 'await' keyword because access is asynchronous.

    Explanation: When accessing actor methods from outside the actor, you must use 'await' because such access may suspend to preserve isolation. Ignoring 'await' results in a compile-time error. The 'async' keyword is for marking function declarations, not calls. While 'Task' can start a new task, it's not required just for calling an actor method.

  5. Nonisolated Methods

    If a method inside a Swift actor is marked 'nonisolated', what does this mean?

    1. It must not contain any code.
    2. It disables concurrency for all actor methods.
    3. It can be accessed without actor isolation, often for static or pure computations.
    4. It is the only method that can read actor properties.

    Explanation: A 'nonisolated' method does not need actor isolation, making it accessible from outside actors without 'await'. This is useful for static or side-effect-free code, not for exclusive property access. It does not disable concurrency nor require the method to be empty.

  6. Async Properties

    Which of the following is true about accessing a mutable property of an actor from outside the actor?

    1. You must use an async method or computed property with 'await' to access it.
    2. You can access it directly without any restrictions.
    3. You must use the 'synchronized' keyword.
    4. It can only be accessed from global functions.

    Explanation: Accessing mutable properties of actors from outside requires an asynchronous context; you must use an async getter or method and 'await'. Direct access is not allowed for safety. There is no 'synchronized' keyword, and properties are not limited to global function access.

  7. Main Actor Attribute

    What is the purpose of the @MainActor attribute in Swift concurrency?

    1. It creates a new actor named 'Main'.
    2. It ensures that the annotated function or property executes on the main thread.
    3. It disables concurrency for the function.
    4. It prevents the function from being asynchronous.

    Explanation: '@MainActor' guarantees that the marked method or property runs on the main thread, which is vital for UI updates. It does not create an actor instance nor disable concurrency. It does not prevent code from being asynchronous but provides thread-safety for main-thread operations.

  8. Structured Concurrency

    In Swift, which construct is most commonly used to create a group of child tasks that run concurrently and are awaited as a group?

    1. ActorCluster
    2. TaskGroup
    3. asyncQueue
    4. ParallelBlock

    Explanation: 'TaskGroup' enables the creation and management of a set of related tasks that can run in parallel and whose results can be awaited collectively. 'asyncQueue', 'ActorCluster', and 'ParallelBlock' are not valid constructs in Swift concurrency for this purpose. Task groups offer structured management and error handling for concurrent code.

  9. Async Error Handling

    When calling an async function that can throw errors, which keywords do you use together in Swift?

    1. 'catch' and 'async'
    2. 'try' and 'await'
    3. 'handle' and 'suspend'
    4. 'throw' and 'task'

    Explanation: When calling an async function that may throw, you use both 'try' (for throwing) and 'await' (for async) together. 'catch' is for handling errors, not for calling; 'throw' is used within functions to signal errors. 'handle' and 'suspend' are not relevant Swift keywords here.

  10. Task Priority

    What is the primary benefit of assigning a priority when creating a new Task in Swift concurrency?

    1. Priority makes tasks immune to cancellation.
    2. Priority forces the task to always run on the main thread.
    3. It increases the memory allocated to the task.
    4. Higher priority tasks are scheduled with preference, potentially running sooner than lower priority tasks.

    Explanation: Assigning a priority suggests to the scheduler that some tasks should be executed sooner than others, but it does not guarantee main-thread execution. Priority does not affect memory allocation or make tasks uncancelable. It is primarily a scheduling hint for improved responsiveness in concurrency.