Context
I have a Mac app that uses the old QuickLook protocols: QLPreviewPanelDataSource and QLPreviewPanelDelegate. You select a row in an NSTableView, hit the spacebar, and you get the QuickLook preview. Standard stuff:
@MainActor
final class SomeController: NSTableViewDataSource, QLPreviewPanelDataSource
{
private var tableView: NSTableView
func numberOfPreviewItems(in panel: QLPreviewPanel!) -> Int {
return tableView.numberOfSelectedRows
}
}
Problem
I'm adopting Actors and Swift Concurrency in this app. SomeController is now assigned to @MainActor as it should be, since it controls UI. But this brings warnings for the -numberOfPreviewItems() implementation:
Main actor-isolated instance method 'numberOfPreviewItems(in:)' cannot be used to satisfy nonisolated protocol requirement
QLPreviewPanelDataSource is not decorated with @MainActor, which would obviously solve the problem. I cannot simply mark the function nonisolated, since it touches tableView, which IS isolated to the Main Actor. And I cannot await an access, since the protocol method does not support concurrency.
Everything works fine, of course, but having 30-some spurious build warnings is a giant distraction.
Question
What is the correct way to silence these warnings assuming:
Apple will never update the protocols with the
@MainActordecoration. (Radars to do so are unanswered for years.)I want to keep the
Strict Concurrency Checkingbuild setting set tocompleteto catch other, legitimate issues.
As you’ve pointed out, Apple has not isolated some legacy Objective-C classes, and given the requests have been open a while, it doesn’t seem like they will. Given this, it doesn’t seem possible to isolate an entire object without access to the object or protocol definition.
To address this isolation issue, Apple has provided this. I found this after running across this question when I had a similar issue
I was building an ARKit feature and needed to conform to
ARSCNViewDelegate, which is locked to the main thread in Objective-C, but considerednonisolatedwhen it came toConcurrency. Since the delegate method returns a value, I couldn't wrap the body in aTask.This is what worked for me:
No warnings, no errors.