运行时需要顶部中断[context evaluateScript:js]
,但是在文档和Google中找不到方法。有人可以帮忙吗?
答案 0 :(得分:1)
如果您使用JSContext
的{{1}}方法。由于上下文中没有取消方法,因此您无法停止它。而且iOS不喜欢macOS可以使用XPC,因此无法停止外部运行环境。
但是,有一种解决方法。只是认为evaluateJavaScript
喜欢浏览器。脚本在进行中。如何通过外部事件停止它。最方便的方法是构造自己的运行循环。将任务缩小并放入队列。
我导出了一个本地计时器,每隔几秒钟就会在一次downloadWithHandler methold上调用javascript处理程序,并将JSContext
设置为true。运行循环将停止,并且JSContext eval到达整个脚本的结尾并返回。
母语:
isCancelled
脚本:
let script = viewModel.string
let context = EAJSContext()!
// context will be dealloc after finish if not retain here.
// not retain it to debugging
// viewModel.context = context
DispatchQueue.global(qos: .background).async {
// inject helper metholds
JavaScriptCoreHelper().config(context: context)
// export download(handler:) method
Emulator.configure(context: context)
let result = context.evaluateScript(script)
print("context return result: \(result)")
}
输出:
var emulator = Emulator.create();
var taskIsFinish = false;
const promiseA = new Promise( (resolve, reject) => {
emulator.downloadWithHandler( (response) => {
// native pass dictionary
var isFinish = response["isFinish"];
var isCancelled = response["isCancelled"];
var date = response["date"];
console.log("isFinish: " + isFinish);
console.log("isCancelled: " + isCancelled);
console.log("date: " + date);
if (isFinish || isCancelled) {
resolve(date);
}
});
});
promiseA
.then( (val) => {
console.log("asynchronous logging has val: " + val)
taskIsFinish = true
})
while(!taskIsFinish) {
// long task in queue
sleep(1);
console.log('long task');
}
(如果评估完成后上下文未取消初始化,则内存可能正在泄漏。)
包装本机Worker类中的上下文。并设置标志,以使该任务在任务取消时快速返回带有空结果的回调。不要保留并扔掉它。
答案 1 :(得分:0)
我无法使用JavaScriptCore
使它正常工作。我尝试过:
DispatchWorkItem
中,然后调用cancel()
Operation
中,然后尝试将其取消,以及nil
对OperationQueue
进行编码(实际上会导致应用崩溃)。JavaScriptCore
中的C API和-fno-objc-arc
标志来手动管理内存。这些都不起作用。
已完成的工作是使用WKWebView
,一旦nil
被使用,evaluateJavaScript
函数就会调用其完成处理程序。我发布了一个示例here。
对于任何尝试这样做的人,请记住这是未记录的行为,因此在以后的任何iOS版本中都可能会更改。