-
Notifications
You must be signed in to change notification settings - Fork 24.9k
Description
Consider an iOS native module definition:
#import "RCTBridgeModule.h"
@interface RCT_EXTERN_REMAP_MODULE(Foobar, Foobar, NSObject)
RCT_EXTERN_METHOD(getFoobars:(nonnull NSNumber *)howMany callback:(RCTResponseSenderBlock *)callback)
@end
and an accompanying Swift implementation:
@objc(Foobar)
public class Foobar : NSObject {
static let QUEUE = dispatch_queue_create("com.foobar.foobar", DISPATCH_QUEUE_CONCURRENT)
var methodQueue: dispatch_queue_t {
return Foobar.QUEUE;
}
public func getFoobars(howMany: NSNumber, callback: RCTResponseSenderBlock) {
...
}
}
This setup worked fine in React Native 0.15. But since the upgrade to React Native 0.17 (I leap-frogged 0.16), it crashes randomly in [RCTModuleMethod invokeWithBridge:module:arguments:]
with EXC_BAD_ACCESS
at https://github.com/facebook/react-native/blob/v0.17.0/React/Base/RCTModuleMethod.m#L470 in Thread 18 (com.foobar.foobar).
(lldb) po _invocation
<NSInvocation: 0x165c68b0>
return value: {v} void
target: {@} 0x1653fc90
selector: {:} getFoobars:callback:
argument 2: {@} 0x178bcd90
argument 3: {@?} 0x165f6ca0 (block)
(lldb) po index
3
So it's trying to release the callback argument, but failing -- likely because it's already been released.
Making the module's queue not a concurrent queue, but a serial one (DISPATCH_QUEUE_SERIAL
or simply nil
) seems to make the problem go away.
It seems reasonable to me if React required native modules to only use serial queues, though perhaps that should be documented then. Or perhaps the release mechanism introduced in 71da291 needs some tweaking so it can work with concurrent queues? cc @tadeuzagallo