Hacker News new | ask | show | jobs
by danappelxx 3385 days ago
Ummm [0]

...would appreciate an explanation here.

[0]: https://github.com/airbnb/native-navigation/blob/91ae656192d...

6 comments

When you really, really, really, really, really want to be on the main queue.
This has a feel of it solved a race condition due to scheduling something on a few ticks later. So it might accomplish not only running something on the main queue but also sneakily after something else finished. For example if you call something like this at the end of view did load, other code that also runs on the main thread may run before it. It's async.

Having said that, it kind of feels hacky. I have certainly seen this in various codebases and I can't comment on react native but just with standard iOS programming it often points to a lack of understanding of lifecycle or similar order of when things are happening.

Isn't this the standard "Let the queue pump events" technique for dealing with the async UI elements in iOS that don't always behave like you expect them to - such as the system alerts? I mean, I'm not justifying this code, which looks quite weird, but one of the reasons for it may be that the framework has to allow events to pump through the iOS queues, such that events propagate all the way through to the system alerts ..
Weird. Seems like that would be better done by invoking NSRunLoop APIs...Plus, you know, filing a Radar.
I think it's probably related to issues that arise when performing view actions/animation in the RN equivalent of `-viewWillAppear:` while segue animations are playing. (Short version: it occurs because the RN JavaScript execution thread is asynchronous.)

A concrete example of a problem I had was when setting a text field to be first responder when displayed. The result was that the keyboard was trying to appear a split second after the push segue animation fired.

(IIRC you can reproduce it fairly trivially in a pure native app by calling `-becomeFirstResponder` asynchronously inside a `viewWillAppear:` block. The result was two animations fighting for screen layout, and a giant white empty block where the keyboard should be.)

The solutions were to: a) wait, or b) fire synchronously in `-viewWillAppear:`. Airbnb seem to have chosen a).

Yeah, at the very least I would expect a comment explaining what this is solving.
I've definitely seen an animation issue where the typical _async -> main didn't work, but _after (0.001 seconds or so) on main did. Though I don't remember if it was on Mac or on iOS, or really what the issue was.
Those animation issues pop up often, and you can get around them by using DispatchQueue.main.asyncAfter(.now() + 0.1) but often you can figure out what the actual issue is (i.e., you're likely attempting to present something in the wrong place) and you should do that instead.
That's a horrible fix, introduces jank, and doesn't work cross device.

You normally want a CoreAnimation completion block ([CATransaction setCompletionBlock:^(){}], with an enclosing [CATransaction begin] and [CATransaction end].

Yes, I am saying that it's a horrible fix and you shouldn't do it. Sorry I didn't make that clear.