How task cancellation works with async/await
Cooperative cancellation in Swift Concurrency.
Cancellation is a flag, not a kill; check Task.isCancelled or call checkCancellation, URLSession throws CancellationError automatically.
WHAT THIS TESTS The interviewer wants to confirm you grasp that Swift Concurrency uses cooperative cancellation. A cancelled task is not killed; it is asked to stop, and well-written code honors that request at safe points.
A GOOD ANSWER COVERS Calling cancel() on a Task sets its isCancelled flag and propagates to child tasks in the structured tree. The task keeps running until it next checks. Suspension points provided by the system, including URLSession's data(from:) and data(for:), Task.sleep, and async sequences, detect cancellation and throw CancellationError automatically. So if you await such a call and the task is cancelled, the error surfaces and you can clean up with defer or catch. For your own CPU-bound or chunked work, you poll Task.isCancelled in a loop or call try Task.checkCancellation() at boundaries, then release resources and return or throw.
COMMON WRONG ANSWERS Claiming cancel() immediately tears the task down, or that it can interrupt a synchronous blocking call. Forgetting that withTaskCancellationHandler exists for resources that need active teardown, like closing a stream. Assuming a detached task inherits cancellation from its parent, which it does not.
LIKELY FOLLOW-UPS How to react the instant cancellation happens for a non-async resource: use withTaskCancellationHandler to run a closure when cancelled. Whether cancellation propagates across a TaskGroup: yes, cancelling the group cancels children. How SwiftUI .task ties cancellation to view lifetime: the task is cancelled when the view disappears.
ONE CONCRETE EXAMPLE A search screen kicks off a network call in .task as the user types. When they navigate away or the query changes, SwiftUI cancels the prior task. Because you await URLSession.data, that call throws CancellationError, you skip updating state, and the in-flight request is torn down so it does not waste bandwidth or overwrite fresh results. For a local file parse you would add try Task.checkCancellation() inside the read loop to stop promptly.
Interview question
A long-running async function does heavy CPU work in a tight loop with no awaits. What must you add so calling cancel() actually stops it early?
- a.Nothing; cancel() forcibly terminates any running task
- b.A DispatchQueue.global() wrapper around the loop
- c.Mark the function nonisolated so the runtime can interrupt it
- d.Periodic checks of Task.isCancelled or try Task.checkCancellation()Correct
Why? this is the answer
Cancellation is cooperative, so a loop with no suspension points never observes it unless you poll the flag yourself. cancel() does not forcibly terminate running code.
Just read this? Test yourself on what you have been reading.
Read the original → developer.apple.com
- #ios
- #swift
- #concurrency
- #async-await
- #cancellation
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on ios — each one lists the topics its interview covers.
See open roles