Created
October 25, 2023 15:14
-
-
Save mattmassicotte/5f2450a64724ed9a70fbc935f4681a2d to your computer and use it in GitHub Desktop.
Use non-global actor protocols with global actor types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import AppKit | |
// Make a wrapper for the delegate that maps delegate methods to functions | |
// (Making it a class/inherit from NSObject as needed) | |
final class TextLayoutManagerDelegateAdapter: NSObject { | |
public typealias TextLayoutFragmentProvider = (_ location: NSTextLocation, _ textElement: NSTextElement) -> NSTextLayoutFragment | |
public let textLayoutFragmentProvider: TextLayoutFragmentProvider | |
public init( | |
textLayoutFragmentProvider: @escaping TextLayoutFragmentProvider | |
) { | |
self.textLayoutFragmentProvider = textLayoutFragmentProvider | |
} | |
} | |
// Add conformance to the MainActor-incompatible protocol, | |
// calling out to those function properties | |
extension TextLayoutManagerDelegateAdapter: NSTextLayoutManagerDelegate { | |
func textLayoutManager( | |
_ textLayoutManager: NSTextLayoutManager, | |
textLayoutFragmentFor location: NSTextLocation, | |
in textElement: NSTextElement | |
) -> NSTextLayoutFragment { | |
textLayoutFragmentProvider(location, textElement) | |
} | |
} | |
final class TextViewController: NSViewController { | |
// create the adapter in your MainActor type, accessing whatever internal methods you need | |
private lazy var delegateAdapter: TextLayoutManagerDelegateAdapter? = { | |
.init(textLayoutFragmentProvider: { self.textLayoutFragment(for: $0, in: $1) }) | |
}() | |
init() { | |
super.init(nibName: nil, bundle: nil) | |
// finally, assign the delegate once self is inited | |
textView.textLayoutManager?.delegate = self.delegateAdapter | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment