📖 Scenario: You are building a simple Swift program that uses an actor to manage a counter. You want to add a method that can be called without waiting for the actor's isolation, so it can be accessed quickly and safely from any thread.
🎯 Goal: Create an actor named Counter with a nonisolated method that returns a greeting message. This method should be callable without awaiting the actor.
📋 What You'll Learn
Create an actor named Counter with a variable count initialized to 0
Add a nonisolated method greeting() that returns the string "Hello from Counter!"
Add an isolated method increment() that increases count by 1
Print the result of calling greeting() without awaiting
Print the value of count after calling increment() with awaiting
💡 Why This Matters
🌍 Real World
Actors help manage data safely when multiple parts of a program run at the same time. Nonisolated methods let you quickly get information that doesn't change the data.
💼 Career
Understanding actors and nonisolated methods is important for writing safe and efficient Swift code in apps that use concurrency, such as iOS or macOS applications.
Progress0 / 4 steps
1
Create the Counter actor with a count variable
Create an actor named Counter with a variable count set to 0 inside it.
Swift
Hint
Use the actor keyword to define Counter and add var count = 0 inside.
2
Add a nonisolated greeting() method
Inside the Counter actor, add a nonisolated method named greeting() that returns the string "Hello from Counter!".
Swift
Hint
Use nonisolated func greeting() -> String and return the exact string.
3
Add an isolated increment() method
Inside the Counter actor, add a method named increment() that increases the count variable by 1.
Swift
Hint
Define func increment() and add count += 1 inside.
4
Call greeting() and increment(), then print results
Create an instance of Counter named counter. Print the result of calling counter.greeting() without await. Then awaitcounter.increment() and print the value of counter.count by awaiting a new method getCount() that returns count.
Swift
Hint
Remember to add getCount() to return count. Use await when calling increment() and getCount(). Print the greeting without await.
Practice
(1/5)
1. What is the main purpose of marking a method as nonisolated in a Swift actor?
easy
A. To allow the method to run outside the actor's isolation without needing await
B. To make the method private to the actor
C. To force the method to always run asynchronously
D. To prevent the method from accessing any properties
Solution
Step 1: Understand actor isolation
Actors protect their data by isolating it, so methods usually run inside this isolation.
Step 2: Role of nonisolated
Marking a method nonisolated means it runs outside this isolation and can be called without await.
Final Answer:
To allow the method to run outside the actor's isolation without needing await -> Option A
Quick Check:
Nonisolated method = runs outside isolation without await [OK]
Hint: Nonisolated means no await needed to call method [OK]
Common Mistakes:
Thinking nonisolated methods are private
Assuming nonisolated methods must be async
Believing nonisolated methods cannot access any properties
2. Which of the following is the correct way to declare a nonisolated method inside a Swift actor?
easy
A. func nonisolated greet() { print("Hello") }
B. nonisolated func greet() { print("Hello") }
C. func greet() nonisolated { print("Hello") }
D. func greet() async nonisolated { print("Hello") }
Solution
Step 1: Recall correct syntax for nonisolated
The nonisolated keyword comes before func in the method declaration.
Step 2: Check each option
nonisolated func greet() { print("Hello") } correctly places nonisolated before func. Others place it incorrectly or add unnecessary keywords.
Final Answer:
nonisolated func greet() { print("Hello") } -> Option B
Quick Check:
Keyword nonisolated before func = correct syntax [OK]
Hint: Put nonisolated before func keyword [OK]
Common Mistakes:
Placing nonisolated after func
Adding async unnecessarily
Using nonisolated as a function modifier
3. What will be the output of the following Swift code?
A. Compile error because printHello is nonisolated
B. Hello\n1
C. Hello
D. Runtime error because increment is not awaited
Solution
Step 1: Understand nonisolated method call
The method printHello() is marked nonisolated, so it can be called directly without await.
Step 2: Analyze output
Calling counter.printHello() prints "Hello". The increment method is commented out, so no other output.
Final Answer:
Hello -> Option C
Quick Check:
Nonisolated method prints Hello directly [OK]
Hint: Nonisolated methods run without await and print output [OK]
Common Mistakes:
Expecting increment output without await
Thinking nonisolated causes compile error
Confusing runtime error with compile error
4. Consider this Swift actor code snippet:
actor Logger {
var logs = [String]()
nonisolated func printLog(_ message: String) {
print(message)
}
func addLog(_ message: String) {
logs.append(message)
}
}
let logger = Logger()
logger.printLog("Start")
logger.addLog("Start")
What is the main issue with this code?
medium
A. addLog method must be marked nonisolated
B. Nonisolated method printLog cannot access actor's logs array
C. Nonisolated method printLog causes data race on logs
D. Cannot call addLog without await, causing a compile error
Solution
Step 1: Check method calls
The addLog method is isolated and must be called with await outside the actor.
Step 2: Identify error
Calling logger.addLog("Start") without await causes a compile error.
Final Answer:
Cannot call addLog without await, causing a compile error -> Option D
Quick Check:
Isolated method call requires await [OK]
Hint: Isolated methods need await; nonisolated do not [OK]
Common Mistakes:
Thinking nonisolated can access isolated properties
Assuming addLog can be called without await
Marking all methods nonisolated incorrectly
5. You want to add a nonisolated method to a Swift actor that returns a constant string without accessing any actor-isolated data. Which of the following implementations is correct and safe?
hard
A. nonisolated func status() -> String { return "Ready" }