Reputation: 1705
I am experiencing an issue with my actor when I am trying to call another async function that is static and declared to run on the main-actor. Specifically, the called function executes to the end, but never seems to return control over execution to the caller (my actor).
This results in the code after the function call to never be executed.
In simple terms, it looks like the executing MainThread simply "swallows" the return statement.
Below is a minimal example of what my code (structurally) looks like. What actually happens in the called function are ScreenCaptureKit
calls. I decided to leave them in for clarity.
actor SomeActor {
func myTestFunction() async throws {
print("Before execution")
let returnValue = try await SomeClass.createSCKSnapshot()
print("After execution") // this is never called since the previous await never seems to return execution back to SomeActor
}
}
@MainActor
class SomeClass {
@MainActor public static func createSCKSnapshot() async throws -> (displays: [SCDisplay], windows: [SCWindow], applications: [SCRunningApplication]) {
let shareableContent: SCShareableContent = try await SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: false)
return (shareableContent.displays, shareableContent.windows, shareableContent.applications)
}
}
Now, here you see my actor SomeActor
trying to call SomeClass.createSCKSnapshot()
in one of its isolated functions. Thereby, createSCKSnapshot()
executes just fine including the return statement, but then nothing happens and the print("After execution")
is never executed inside SomeActor
.
Why is that? And how can I bypass this issue and ensure that my program continues execution normally after createSCKSnapshot()
returns?
EDIT:
The app does have permission and uses ScreenCaptureKit throughout various locations in the app, where everything works fine. The only difference is that code from those locations doesn't call the method from inside an actor but from a class. Therefore, I believe it must be some sort of issue with actors.
Upvotes: 1
Views: 578
Reputation: 1705
The issue arises because there turned out to be blocking code on my actor, never freeing up the actor. Thereby, the function was waiting inside the queue for the actor to free up, which never happened.
If you run in a similar issue, use Xcode Instruments to profile your app and use the "Swift Concurrency" mode to see what work is executed on actors, and what work is waiting in an actor's queue.
Upvotes: 2