dart-lang / native

Dart packages related to FFI and native assets bundling.
BSD 3-Clause "New" or "Revised" License
155 stars 43 forks source link

Document a supported pattern for a Dart equivalent to Obj-C's `@selector(...)` #1580

Closed stuartmorgan closed 1 month ago

stuartmorgan commented 1 month ago

Trying to convert some CADisplayLink code to Dart, I realized that it wasn't obvious how to interact with APIs that use the target:selector: pattern (like +[CADisplayLink displayLinkWithTarget:selector:). Since there are no docs for it, I generated it and looked at the output, and saw that the type is ffi.Pointer<objc.ObjCSelector>. Okay, so how do I make one? Jumping to the definition (in pkg:objective_c) just gives me:

typedef ObjCSelector = _ObjCSelector;

final class _ObjCSelector extends ffi.Opaque {}

Which is not helpful. The only answer I'm aware of to that question is pkg:objective_c's registerName, but:

  1. I only know that is there is because I had previously dug all the way into the generated bindings to make my own manual bindings as workarounds for ffigen bugs (e.g., protocol methods at the time), and
  2. registerName's (only) documentation is /// Only for use by ffigen bindings..

While this isn't a super common pattern in Apple SDKs, especially since newer code generally uses blocks instead, it is around, so we should have a clear support path for it.

stuartmorgan commented 1 month ago

Oh, a much more common use case for this would be respondsToSelector: for optional protocol methods.

liamappelbe commented 1 month ago

I'll make registerName public and maybe rename it. Might also be convenient to add a string extension method: "foo:bar:".toSelector(). A heavier change would be to add some sort of Selector class to wrap Pointer<ObjCSelector>, but I don't see a need for it, and this would require special casing in ffigen to use the wrapper class in place of the raw pointer.