From de18977b420bbc167a22e994923802b9a9cef14a Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Thu, 21 Mar 2019 10:59:31 -0700 Subject: [PATCH] Fixed native animated crash because of thread-safe issue (#24063) Summary: After we imported Fabric surface presenter observer mechanism, the thread-safe issue comes up, `operations` may read-write on main thread and shadow queue. ``` 2019-03-20 15:53:21.249742+0800 RNTester[36039:1402802] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x60000396a730> was mutated while being enumerated.' *** First throw call stack: ( 0 CoreFoundation 0x00000001083221bb __exceptionPreprocess + 331 1 libobjc.A.dylib 0x0000000106a07735 objc_exception_throw + 48 2 CoreFoundation 0x000000010831ee9c __NSFastEnumerationMutationHandler + 124 3 RNTester 0x00000001048c8784 -[RCTNativeAnimatedModule didMountComponentsWithRootTag:] + 596 4 RNTester 0x000000010491423e -[RCTSurfacePresenter mountingManager:didMountComponentsWithRootTag:] + 1662 5 RNTester 0x00000001048f54e9 -[RCTMountingManager _performMountItems:rootTag:] + 1369 6 RNTester 0x00000001048f4eba __62-[RCTMountingManager performTransactionWithMutations:rootTag:]_block_invoke + 58 7 RNTester 0x0000000104710d1d __RCTExecuteOnMainQueue_block_invoke + 29 8 libdispatch.dylib 0x000000010a4db595 _dispatch_call_block_and_release + 12 9 libdispatch.dylib 0x000000010a4dc602 _dispatch_client_callout + 8 10 libdispatch.dylib 0x000000010a4e999a _dispatch_main_queue_callback_4CF + 1541 11 CoreFoundation 0x00000001082873e9 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9 12 CoreFoundation 0x0000000108281a76 __CFRunLoopRun + 2342 13 CoreFoundation 0x0000000108280e11 CFRunLoopRunSpecific + 625 14 GraphicsServices 0x000000010e0c11dd GSEventRunModal + 62 15 UIKitCore 0x000000011567281d UIApplicationMain + 140 16 RNTester 0x0000000104553380 main + 112 17 libdyld.dylib 0x000000010a552575 start + 1 ) ``` [iOS] [Fixed] - Fixed native animated crash because of thread-safe issue Pull Request resolved: https://github.com/facebook/react-native/pull/24063 Differential Revision: D14563994 Pulled By: shergin fbshipit-source-id: 98970c8993b7b794273ed3a8c40dbbce147e1f4b --- .../NativeAnimation/RCTNativeAnimatedModule.m | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Libraries/NativeAnimation/RCTNativeAnimatedModule.m b/Libraries/NativeAnimation/RCTNativeAnimatedModule.m index 47d4162c840..5b8e165b4b6 100644 --- a/Libraries/NativeAnimation/RCTNativeAnimatedModule.m +++ b/Libraries/NativeAnimation/RCTNativeAnimatedModule.m @@ -236,19 +236,27 @@ RCT_EXPORT_METHOD(removeAnimatedEventFromView:(nonnull NSNumber *)viewTag - (void)willMountComponentsWithRootTag:(NSInteger)rootTag { RCTAssertMainQueue(); - for (AnimatedOperation operation in _preOperations) { + __block NSArray *preOperations; + RCTUnsafeExecuteOnUIManagerQueueSync(^{ + preOperations = self->_preOperations; + self->_preOperations = [NSMutableArray new]; + }); + for (AnimatedOperation operation in preOperations) { operation(self->_nodesManager); } - _preOperations = [NSMutableArray new]; } - (void)didMountComponentsWithRootTag:(NSInteger)rootTag { RCTAssertMainQueue(); - for (AnimatedOperation operation in _operations) { + __block NSArray *operations; + RCTUnsafeExecuteOnUIManagerQueueSync(^{ + operations = self->_operations; + self->_operations = [NSMutableArray new]; + }); + for (AnimatedOperation operation in operations) { operation(self->_nodesManager); } - _operations = [NSMutableArray new]; } #pragma mark - RCTUIManagerObserver