Skip to content

Commit

Permalink
Changed default method queue to a background queue.
Browse files Browse the repository at this point in the history
  • Loading branch information
nicklockwood committed Apr 20, 2015
1 parent 5e2f90a commit 5ce9fa4
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 32 deletions.
5 changes: 5 additions & 0 deletions Libraries/ActionSheetIOS/RCTActionSheetManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ - (instancetype)init
return self;
}

- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}

RCT_EXPORT_METHOD(showActionSheetWithOptions:(NSDictionary *)options
failureCallback:(RCTResponseSenderBlock)failureCallback
successCallback:(RCTResponseSenderBlock)successCallback)
Expand Down
5 changes: 5 additions & 0 deletions Libraries/Geolocation/RCTLocationObserver.m
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ - (void)dealloc
_locationManager.delegate = nil;
}

- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}

#pragma mark - Private API

- (void)beginLocationUpdates
Expand Down
13 changes: 9 additions & 4 deletions Libraries/LinkingIOS/RCTLinkingManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ - (void)dealloc
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (dispatch_queue_t)methodQueue
{
return dispatch_queue_create("com.facebook.React.LinkingManager", DISPATCH_QUEUE_SERIAL);
}

+ (BOOL)application:(UIApplication *)application
openURL:(NSURL *)URL
sourceApplication:(NSString *)sourceApplication
Expand All @@ -56,16 +61,16 @@ - (void)handleOpenURLNotification:(NSNotification *)notification

RCT_EXPORT_METHOD(openURL:(NSURL *)URL)
{
// Doesn't really matter what thread we call this on since it exits the app
[[UIApplication sharedApplication] openURL:URL];
}

RCT_EXPORT_METHOD(canOpenURL:(NSURL *)URL
callback:(RCTResponseSenderBlock)callback)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
BOOL canOpen = [[UIApplication sharedApplication] canOpenURL:URL];
callback(@[@(canOpen)]);
});
// This can be expensive, so we deliberately don't call on main thread
BOOL canOpen = [[UIApplication sharedApplication] canOpenURL:URL];
callback(@[@(canOpen)]);
}

- (NSDictionary *)constantsToExport
Expand Down
10 changes: 5 additions & 5 deletions React/Base/RCTBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ extern NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass);
/**
* This method is used to call functions in the JavaScript application context.
* It is primarily intended for use by modules that require two-way communication
* with the JavaScript code. Method should be regsitered using the
* with the JavaScript code. Method should be registered using the
* RCT_IMPORT_METHOD macro below. Attempting to call a method that has not been
* registered will result in an error.
* registered will result in an error. Safe to call from any thread.
*/
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args;

Expand Down Expand Up @@ -112,17 +112,17 @@ static const char *__rct_import_##module##_##method##__ = #module"."#method;
@property (nonatomic, readonly, getter=isLoading) BOOL loading;

/**
* Reload the bundle and reset executor and modules.
* Reload the bundle and reset executor & modules. Safe to call from any thread.
*/
- (void)reload;

/**
* Add a new observer that will be called on every screen refresh
* Add a new observer that will be called on every screen refresh.
*/
- (void)addFrameUpdateObserver:(id<RCTFrameUpdateObserver>)observer;

/**
* Stop receiving screen refresh updates for the given observer
* Stop receiving screen refresh updates for the given observer.
*/
- (void)removeFrameUpdateObserver:(id<RCTFrameUpdateObserver>)observer;

Expand Down
36 changes: 19 additions & 17 deletions React/Base/RCTBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ @implementation RCTModuleMethod
NSMethodSignature *_methodSignature;
NSArray *_argumentBlocks;
NSString *_methodName;
dispatch_block_t _methodQueue;
}

static Class _globalExecutorClass;
Expand Down Expand Up @@ -762,6 +763,7 @@ @implementation RCTBridge
{
RCTSparseArray *_modulesByID;
RCTSparseArray *_queuesByID;
dispatch_queue_t _methodQueue;
NSDictionary *_modulesByName;
id<RCTJavaScriptExecutor> _javaScriptExecutor;
Class _executorClass;
Expand All @@ -787,7 +789,6 @@ - (instancetype)initWithBundleURL:(NSURL *)bundleURL
[self setUp];
[self bindKeys];
}

return self;
}

Expand All @@ -797,6 +798,7 @@ - (void)setUp
_javaScriptExecutor = RCTCreateExecutor(executorClass);
_latestJSExecutor = _javaScriptExecutor;
_eventDispatcher = [[RCTEventDispatcher alloc] initWithBridge:self];
_methodQueue = dispatch_queue_create("com.facebook.React.BridgeMethodQueue", DISPATCH_QUEUE_SERIAL);
_displayLink = [[RCTDisplayLink alloc] initWithBridge:self];
_frameUpdateObservers = [[NSMutableSet alloc] init];
_scheduledCalls = [[NSMutableArray alloc] init];
Expand Down Expand Up @@ -850,11 +852,14 @@ - (void)setUp
}
}

// Get method queue
// Get method queues
_queuesByID = [[RCTSparseArray alloc] init];
[_modulesByID enumerateObjectsUsingBlock:^(id<RCTBridgeModule> module, NSNumber *moduleID, BOOL *stop) {
if ([module respondsToSelector:@selector(methodQueue)]) {
_queuesByID[moduleID] = [module methodQueue] ?: dispatch_get_main_queue();
dispatch_queue_t queue = [module methodQueue];
if (queue) {
_queuesByID[moduleID] = queue;
}
}
}];

Expand Down Expand Up @@ -895,11 +900,6 @@ - (void)setUp
} else {
[[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptDidLoadNotification
object:self];

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reload)
name:RCTReloadNotification
object:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reload)
Expand Down Expand Up @@ -1205,7 +1205,7 @@ - (void)_handleBuffer:(id)buffer context:(NSNumber *)context
[_modulesByID enumerateObjectsUsingBlock:^(id<RCTBridgeModule> module, NSNumber *moduleID, BOOL *stop) {
if ([module respondsToSelector:@selector(batchDidComplete)]) {
dispatch_queue_t queue = _queuesByID[moduleID];
dispatch_async(queue ?: dispatch_get_main_queue(), ^{
dispatch_async(queue ?: _methodQueue, ^{
[module batchDidComplete];
});
}
Expand Down Expand Up @@ -1240,7 +1240,7 @@ - (BOOL)_handleRequestNumber:(NSUInteger)i

__weak RCTBridge *weakSelf = self;
dispatch_queue_t queue = _queuesByID[moduleID];
dispatch_async(queue ?: dispatch_get_main_queue(), ^{
dispatch_async(queue ?: _methodQueue, ^{
RCTProfileBeginEvent();
__strong RCTBridge *strongSelf = weakSelf;

Expand Down Expand Up @@ -1320,13 +1320,15 @@ - (void)removeFrameUpdateObserver:(id<RCTFrameUpdateObserver>)observer

- (void)reload
{
if (!_loading) {
// If the bridge has not loaded yet, the context will be already invalid at
// the time the javascript gets executed.
// It will crash the javascript, and even the next `load` won't render.
[self invalidate];
[self setUp];
}
dispatch_async(dispatch_get_main_queue(), ^{
if (!_loading) {
// If the bridge has not loaded yet, the context will be already invalid at
// the time the javascript gets executed.
// It will crash the javascript, and even the next `load` won't render.
[self invalidate];
[self setUp];
}
});
}

+ (void)logMessage:(NSString *)message level:(NSString *)level
Expand Down
26 changes: 20 additions & 6 deletions React/Base/RCTBridgeModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,32 @@ typedef void (^RCTResponseSenderBlock)(NSArray *response);

/**
* The queue that will be used to call all exported methods. If omitted, this
* will default the main queue, which is recommended for any methods that
* interact with UIKit. If your methods perform heavy work such as filesystem
* or network access, you should return a custom serial queue. Example:
* will call on the default background queue, which is avoids blocking the main
* thread.
*
* If the methods in your module need to interact with UIKit methods, they will
* probably need to call those on the main thread, as most of UIKit is main-
* thread-only. You can tell React Native to call your module methods on the
* main thread by returning a reference to the main queue, like this:
*
* - (dispatch_queue_t)methodQueue
* {
* return dispatch_get_main_queue();
* }
*
* If your methods perform heavy work such as synchronous filesystem or network
* access, you probably don't want to block the default background queue, as
* this will stall other methods. Instead, you should return a custom serial
* queue, like this:
*
* - (dispatch_queue_t)methodQueue
* {
* return dispatch_queue_create("com.mydomain.FileQueue", DISPATCH_QUEUE_SERIAL);
* }
*
* Alternatively, if only some methods on the module should be executed on a
* background queue you can leave this method unimplemented, and simply
* dispatch_async() within the method itself.
* Alternatively, if only some methods of the module should be executed on a
* particular queue you can leave this method unimplemented, and simply
* dispatch_async() to the required queue within the method itself.
*/
- (dispatch_queue_t)methodQueue;

Expand Down
5 changes: 5 additions & 0 deletions React/Modules/RCTAlertManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ - (instancetype)init
return self;
}

- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}

/**
* @param {NSDictionary} args Dictionary of the form
*
Expand Down
5 changes: 5 additions & 0 deletions React/Modules/RCTStatusBarManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ static BOOL RCTViewControllerBasedStatusBarAppearance()

RCT_EXPORT_MODULE()

- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}

RCT_EXPORT_METHOD(setStyle:(UIStatusBarStyle)statusBarStyle
animated:(BOOL)animated)
{
Expand Down
5 changes: 5 additions & 0 deletions React/Modules/RCTTiming.m
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ - (void)dealloc
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}

- (BOOL)isValid
{
return _bridge != nil;
Expand Down

0 comments on commit 5ce9fa4

Please sign in to comment.