Я использовал web3js для взаимодействия с узлом Ethereum в моем iOS-приложении с Objective-C.Поскольку некоторые функции в 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, это работает хорошо.(Это хорошо работает отдельно.)
Спасибо!