TIL: CATiledLayer and Swift Concurrency do not mix.
I did the trick where UIView.layerClass returns CATiledLayer.self so my (large) UIView is performant. But that means parts of UIView now get called on background threads, and Swift._checkExpectedExecutor() gets all assert-y.
Not sure if there's a way around this.
@andyfinnell I’m certain there is. First thing do is check if any closures that execute on the background are missing @.Sendable. Super common.
@mattiem The assert appears to be happening in the prologue of drawRect (or any property/method I override) *before* it ever gets to my code.
My assumption (which might be wrong) is Swift is inserting the asserts since UIViews are marked MainActor. To test this I marked the overridden method as nonisolated and that did remove the asserts.
@andyfinnell That’s exactly how it works. Ok huh so that feature changes the isolation of drawRect.
I guess it is wrong to be MainActor in the SDK. Which kinda makes sense because I think I’ve run into stuff like this with AppKit too…
@andyfinnell Could you use NSObjectProxy around the layer to intercept any invocations, and then whenever an API call happens off-main-thread you re-invoke on main thread?