我使用Objective-C在我的iOS应用中使用web3js与以太坊节点进行交互。由于js中的某些函数未同步,因此我需要在Obj-c代码中设置一个回调函数以获取结果。它运作良好。但是,如果我依次调用它们(在一个函数中),它会异常工作。这是我的代码段
//Objective-C
// js callback
_jsContext[@"replyJSonString"] = ^(NSString* dicResult, NSString* error) {
DDLogDebug(@"reply from js: %@ - error: %@", dicResult, error);
if(error && ![error isEqualToString:@"null"]) {
_asyncCallResult = error; return;
}
_asyncCallResult = dicResult;
dispatch_semaphore_signal(_semaphore);
-(NSString*) global_getMemberInfo:(NSString*) pid withAPP:(NSString*) app
{
DDLogDebug(@"global_getMemberInfo");
NSString* ret = [self exeJSFunctionFromAsync:JS_FUNC_GET_MEMBER_INFO withParam:@[pid, app]];
if([self isError:ret])
@throw [DTCO_Exception exceptionWithReason:@"global_getMemberInfo function error" userInfo:nil];
return ret;
}
-(NSString*) member_getMemberDetails:(NSString*) pid withTag:(NSString*) tag
{
DDLogDebug(@"member_getMemberDetails");
NSString* ret = [self exeJSFunctionFromAsync:JS_FUNC_GET_MEMBER_DETAILS withParam:@[pid, tag]];
if([self isError:ret])
@throw [DTCO_Exception exceptionWithReason:@"global_getMemberDetails function error" userInfo:nil];
return ret;
}
-(NSString*) exeJSFunctionFromAsync:(NSString*) func withParam: (NSArray*) param
{
JSValue* jsFunc = _jsContext[func];
if([[jsFunc toString] isEqualToString:@"undefined"] )
@throw [DTCO_Exception exceptionWithReason:@"JS file is not loaded correctly." userInfo:nil];
JSValue* ret = [jsFunc callWithArguments:param];
dispatch_semaphore_wait(_semaphore, dispatch_time(DISPATCH_TIME_NOW, 2*NSEC_PER_SEC));
DDLogDebug(@"exe [%@] ret: %@", func, _asyncCallResult);
return _asyncCallResult;
}
JavaScript
// javascript
function global_getMemberInfo(pid, app) {
try
{
if(typeof global_web3 != 'undefined') {
var globalContract = new global_web3.eth.Contract(globalContractABI, globalContractAddress,
{from:pid, gasPrice: '2000000000'});
var contractFunc = globalContract.methods.get_member_info(pid, 'idgo');
contractFunc.call(function(error, result) { replyJSonString(JSON.stringify(result), error);
});
}else{
return "web3 undefined!";
}
}
catch(e)
{
return "exception: "+e;
}
}
function member_getMemberDetails(pid, tag) {
try
{
if(typeof global_web3 != 'undefined') {
var memberContract = new global_web3.eth.Contract(memberContractABI, memberContractAddress,
{from:pid, gasPrice: '2000000000'});
var contractFunc = memberContract.methods.getDetail(pid, tag);
contractFunc.call(function(error, result) { replyJSonString(JSON.stringify(result), error);
});
}else{
return "web3 undefined!";
}
}
catch(e)
{
return "exception: "+e;
}
}
如果我像这样一次调用两个函数,
+(NSString*) getMemberInfo:
{
ID_MemberInfo* info = [api global_getMemberInfo:@"0x300..."
ID_MemberDetails* details = [api member_getMemberDetails:@"0x300..." andTag:@"tag"];
...
}
第二个异常,这是日志
2018-12-05 14:42:13:007 IDGODemoSDK[25744:1093451] global_getMemberInfo
2018-12-05 14:42:13:024 IDGODemoSDK[25744:1093451] exe [member_getMemberDetails] ret: (null)
2018-12-05 14:42:13:209 IDGODemoSDK[25744:1093519] reply from js: {...} - error: null
2018-12-05 14:42:13:007 IDGODemoSDK[25744:1093451] member_getMemberDetails
2018-12-05 14:42:20:018 IDGODemoSDK[25744:1093451] exe [member_getMemberDetails] ret: (null)
2018-12-05 14:42:20:019 IDGODemoSDK[25744:1093451] getMemberDetails EX - global_getMemberDetails function error
2018-12-05 14:42:20.020 IDGODemoSDK[25744:1093451] global_getMemberDetails function error
2018-12-05 14:42:20:032 IDGODemoSDK[25744:1093519] reply from js: {...} - error: null
似乎线程[1093519](回调线程)在第二次调用时被阻止。无论我等待了多长时间,在第二次调用中停止等待后都立即调用了回调。第二次回调似乎有点问题。如果两个js函数都没有回调obj-c,则效果很好。 (它单独工作很好。)
谢谢!