Skip to content

Pattern for interacting with the main thread #42

@jlongster

Description

@jlongster

I exported a function on my controller:

- (void)loadMesh:(NSString *)path {
    RCT_EXPORT();
    node.mesh = [REMeshCache meshNamed:path];
}

This is called when selecting an item from a list:

var controller = require('NativeModules').TeapotController;

// ....

selectModel: function(file) {
  controller.loadMesh(file);
},

I've been trying to debug why OpenGL crashes, and I finally realized that my OpenGL context doesn't exist. Which made me realize that this method in Obj-C is not running on the main thread. It's running in a different thread which all calls into Obj-C seem to run on.

I'm not familiar with iOS, so this is over my head. Is there a simple pattern I can use to interact with the main thread? How do I send a message to it?

I realize this not usually needed, and most custom native modules can probably be run standalone, but I'm basically implementing a custom view that needs to render on the main thread (not technically true, just a custom controller to a normal view, but still).

Activity

jlongster

jlongster commented on Feb 4, 2015

@jlongster
Author

Oh haha. RTFM. It's actually pretty simple:

- (void)loadMesh:(NSString *)path {
    RCT_EXPORT();

    dispatch_async(dispatch_get_main_queue(), ^{
        node.mesh = [REMeshCache meshNamed:path];
    });
}

That works!

vjeux

vjeux commented on Feb 4, 2015

@vjeux
Contributor

If you are bored, would be awesome to compile this into some sort of docs :)

jlongster

jlongster commented on Feb 4, 2015

@jlongster
Author

If you are bored, would be awesome to compile this into some sort of docs :)

I almost filed an issue about that, actually! I was going to ask if there's a place you want us to contribute to docs. I can certainly write done a bunch of small stuff I've learned. Where would you like it, and what format?

vjeux

vjeux commented on Feb 4, 2015

@vjeux
Contributor

We're going to have official docs before we open this repo to everyone. They'll be in the docs folder in markdown, the same way React is. If you can start writing them in markdown and in the docs folder with whatever you think is useful for people, that would be awesome!

https://github.com/facebook/react/tree/master/docs/docs

frantic

frantic commented on Feb 6, 2015

@frantic
Contributor

Looks like this is a very common pattern - native modules that run on main thread. Maybe we could do something like:

- (void)loadMesh:(NSString *)path {
    RCT_EXPORT_ON_MAIN_THREAD();
    node.mesh = [REMeshCache meshNamed:path];
}

@a2 / @nicklockwood - any thoughts?

a2

a2 commented on Feb 6, 2015

@a2
Contributor

The JS bridge is meant to be asynchronous and therefore runs off the main thread. I personally think that if something should happen on a specific thread/queue, it is the caller's responsibility. Apple's documentation often says that callbacks can happen on private threads/queues and that you should dispatch if necessary.

frantic

frantic commented on Feb 6, 2015

@frantic
Contributor

@a2 great answer, totally makes sense!

nicklockwood

nicklockwood commented on Feb 6, 2015

@nicklockwood
Contributor

Whilst @a2 is quite correct, I wonder if it might make sense to change the thread that we call back to modules on to main.

We don't call module methods on the JS thread, we actually call them on the shadow thread, which is a seperate thread used by the RCTUIManager to do layout calculations.

But other than the UIManager, the vast majority of modules either don't care what thread they run on, or would prefer to run their methods on the main thread. Perhaps then, the bridge should call back to main, and the UIManager can dispatch to the shadow thread?

It would save having to dispatch_async inside every single module's methods for the sake of catering to the requirements of one specific module.

locked as resolved and limited conversation to collaborators on May 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @jlongster@frantic@vjeux@a2@nicklockwood

        Issue actions

          Pattern for interacting with the main thread · Issue #42 · facebook/react-native