NativeScript对接Stripe Terminal iOS SDK异步回调调用completion崩溃求助
问题根因
EXC_BAD_ACCESS code=2崩溃是两个NativeScript与iOS原生SDK交互的常见问题共同导致的:
- 异步场景下原生completion block被提前释放:同步调用时completion还处于Stripe SDK的调用上下文,不会被ARC回收;但HTTP请求是异步操作,回调触发时原生调用栈已经退出,没有被强引用的completion block会被释放,后续调用就触发野指针访问。
- 线程不匹配:Stripe Terminal iOS SDK要求所有completion必须在主线程调用,而NativeScript的HTTP回调默认运行在后台线程,直接调用会触发线程安全崩溃。
修复方案
修改代码显式强持有completion,并将回调调用逻辑抛到主线程执行即可,同时要补全错误分支的处理,避免请求失败时SDK无响应:
import { strongRef, MainThread } from '@nativescript/core' iOSFetchConnectionToken(completion: (p1: string, p2: NSError) => void) { // 强持有completion,避免异步过程中被ARC释放 const retainedCompletion = strongRef(completion); Http.request({ url: DemoSharedStripeterminalBasic.serverAddress, method: 'POST', headers: { "Content-Type": "application/json", "Stripe-Public-Key": this.stripeTestKey }, content: JSON.stringify({ connectedAccountId: this.connectedAccountId }) }).then(response => { const result = response.content?.toJSON(); const secret = result.secret; // 切换到主线程调用completion MainThread.run(() => { retainedCompletion.get()(secret, null as unknown as NSError); // 调用完成后解除强引用,避免内存泄漏 strongRef.release(retainedCompletion); }) }).catch(err => { // 错误场景也要回调SDK,避免SDK卡住 MainThread.run(() => { const nativeError = NSError.errorWithDomainCodeUserInfo("ConnectionTokenError", -1, { NSLocalizedDescriptionKey: err.message }); retainedCompletion.get()(null, nativeError); strongRef.release(retainedCompletion); }) }) }
额外注意事项
如果使用async/await写法,逻辑和上面一致:只要在进入异步逻辑前先强持有completion,调用时切主线程,调用后释放即可。
内容的提问来源于stack exchange,提问作者Court Hoang
相关产品推荐
相关产品推荐

