Found during #114 review — iOS has both races #114 closes on Android: (1) event handles are bare slot indices (mob_send_tap, ios/mob_nif.m ~209-226, bounds check only) so a callback captured by a superseded render resolves against whatever handler now owns the slot — on Android master this misrouted 29/100 taps under a render storm on hardware; (2) every sender captures tag under tap_mutex but calls enif_make_copy AFTER unlock (e.g. mob_send_change ~584-592) — the exact use-after-free window #114 closes by copying under the lock. When #114's revision lands, port both: generation-tagged handles + copy-under-lock, and keep the sender.ex moduledoc honest about platform shape in the interim.
Found during #114 review — iOS has both races #114 closes on Android: (1) event handles are bare slot indices (mob_send_tap, ios/mob_nif.m ~209-226, bounds check only) so a callback captured by a superseded render resolves against whatever handler now owns the slot — on Android master this misrouted 29/100 taps under a render storm on hardware; (2) every sender captures tag under tap_mutex but calls enif_make_copy AFTER unlock (e.g. mob_send_change ~584-592) — the exact use-after-free window #114 closes by copying under the lock. When #114's revision lands, port both: generation-tagged handles + copy-under-lock, and keep the sender.ex moduledoc honest about platform shape in the interim.