^{
RCTJSCExecutor *strongSelf = weakSelf;
if (!strongSelf || !strongSelf.isValid) {
return;
}
NSError *error;
JSValueRef errorJSRef = NULL;
JSValueRef resultJSRef = NULL;
RCTJSCWrapper *jscWrapper = strongSelf->_jscWrapper;
JSGlobalContextRef contextJSRef = jscWrapper->JSContextGetGlobalContext(strongSelf->_context.ctx);
JSContext *context = strongSelf->_context.context;
JSObjectRef globalObjectJSRef = jscWrapper->JSContextGetGlobalObject(strongSelf->_context.ctx);
// get the BatchedBridge object
JSValueRef batchedBridgeRef = strongSelf->_batchedBridgeRef;
if (!batchedBridgeRef) {
JSStringRef moduleNameJSStringRef = jscWrapper->JSStringCreateWithUTF8CString("__fbBatchedBridge");
batchedBridgeRef = jscWrapper->JSObjectGetProperty(contextJSRef, globalObjectJSRef, moduleNameJSStringRef, &errorJSRef);
jscWrapper->JSStringRelease(moduleNameJSStringRef);
strongSelf->_batchedBridgeRef = batchedBridgeRef;
}
if (batchedBridgeRef != NULL && errorJSRef == NULL && !jscWrapper->JSValueIsUndefined(contextJSRef, batchedBridgeRef)) {
//RN调JS的核心代码
NSLog(@"test1");
// get method
JSStringRef methodNameJSStringRef = jscWrapper->JSStringCreateWithCFString((__bridge CFStringRef)method);
JSValueRef methodJSRef = jscWrapper->JSObjectGetProperty(contextJSRef, (JSObjectRef)batchedBridgeRef, methodNameJSStringRef, &errorJSRef);
jscWrapper->JSStringRelease(methodNameJSStringRef);
if (methodJSRef != NULL && errorJSRef == NULL && !jscWrapper->JSValueIsUndefined(contextJSRef, methodJSRef)) {
JSValueRef jsArgs[arguments.count];
for (NSUInteger i = 0; i < arguments.count; i++) {
jsArgs[i] = [jscWrapper->JSValue valueWithObject:arguments[i] inContext:context].JSValueRef;
}
NSLog(@"test2 ");
resultJSRef = jscWrapper->JSObjectCallAsFunction(contextJSRef, (JSObjectRef)methodJSRef, (JSObjectRef)batchedBridgeRef, arguments.count, jsArgs, &errorJSRef);
} else {
if (!errorJSRef && jscWrapper->JSValueIsUndefined(contextJSRef, methodJSRef)) {
error = RCTErrorWithMessage([NSString stringWithFormat:@"Unable to execute JS call: method %@ is undefined", method]);
}
}
} else {
if (!errorJSRef && jscWrapper->JSValueIsUndefined(contextJSRef, batchedBridgeRef)) {
error = RCTErrorWithMessage(@"Unable to execute JS call: __fbBatchedBridge is undefined");
}
}
if (errorJSRef || error) {
if (!error) {
error = RCTNSErrorFromJSError(jscWrapper, contextJSRef, errorJSRef);
}
onComplete(nil, error);
return;
}
// Looks like making lots of JSC API calls is slower than communicating by using a JSON
// string. Also it ensures that data stuctures don't have cycles and non-serializable fields.
// see [RCTJSCExecutorTests testDeserializationPerf]
id objcValue;
// We often return `null` from JS when there is nothing for native side. JSONKit takes an extra hundred microseconds
// to handle this simple case, so we are adding a shortcut to make executeJSCall method even faster
if (!jscWrapper->JSValueIsNull(contextJSRef, resultJSRef)) {
objcValue = [[jscWrapper->JSValue valueWithJSValueRef:resultJSRef inContext:context] toObject];
}
onComplete(objcValue, nil);}
精简
RCTJSCWrapper *jscWrapper = strongSelf->_jscWrapper;
// get method
JSValueRef jsArgs[arguments.count];
for (NSUInteger i = 0; i < arguments.count; i++)
{
jsArgs[i] = [jscWrapper->JSValue valueWithObject:arguments[i] inContext:context].JSValueRef;
}
resultJSRef = jscWrapper->JSObjectCallAsFunction(contextJSRef, (JSObjectRef)methodJSRef, (JSObjectRef)batchedBridgeRef, arguments.count, jsArgs, &errorJSRef);
id objcValue;
objcValue = [[jscWrapper->JSValue valueWithJSValueRef:resultJSRef inContext:context] toObject];
onComplete(objcValue, nil);
精简
jscWrapper->JSObjectCallAsFunction
JavaScriptCore:JSObjectRef
JS_EXPORT JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception);