Avoid using `RCTUnsafeExecuteOnMainQueueSync` and similar synchronous main queue dispatch methods as they can cause deadlocks, especially in initialization code, dispatch_once blocks, or when called from background threads that may already hold main queue dependencies.
Avoid using RCTUnsafeExecuteOnMainQueueSync
and similar synchronous main queue dispatch methods as they can cause deadlocks, especially in initialization code, dispatch_once blocks, or when called from background threads that may already hold main queue dependencies.
Deadlocks occur when the main queue is waiting for a background queue, and that background queue then tries to synchronously dispatch back to the main queue. This creates a circular dependency where both queues are blocked waiting for each other.
Instead, use asynchronous alternatives like RCTExecuteOnMainQueue
which avoids the jump if already on the main queue, or standard dispatch_async(dispatch_get_main_queue(), ...)
when you need to ensure execution at the end of the main queue.
Example of problematic code:
// BAD - Can cause deadlock
- (void)invalidate {
RCTUnsafeExecuteOnMainQueueSync(^{
if (_didInvalidate) {
return;
}
// ... invalidation logic
});
}
Example of safer alternative:
// GOOD - Uses async dispatch to avoid deadlock
- (void)invalidate {
RCTExecuteOnMainQueue(^{
if (_didInvalidate) {
return;
}
// ... invalidation logic
});
}
This pattern is particularly important in React Native’s multi-threaded environment where JavaScript, UI, and background threads frequently interact.
Enter the URL of a public GitHub repository