调用showManageSubscriptions(in:)关闭订阅管理页后APP崩溃求助
解决
showManageSubscriptions(in:)关闭后APP崩溃的问题 问题根源分析
- @objc函数不支持async throws:Objective-C运行时无法正确处理Swift的
async throws组合函数,这会导致订阅界面关闭后的回调逻辑出错,引发崩溃。 - 重复添加按钮Target:在
viewWillAppear中每次页面出现都给按钮绑定点击事件,会导致按钮被绑定多个相同action,触发时可能产生异常。 - WindowScene获取不可靠:直接取
connectedScenes.first可能拿到非当前活跃的场景,导致界面生命周期管理异常。
修复后的代码
import UIKit import StoreKit class ViewController: UIViewController { @IBOutlet var managerBtn: UIButton! override func viewDidLoad() { super.viewDidLoad() // 仅在viewDidLoad中添加一次target,避免重复绑定 managerBtn.addTarget(self, action: #selector(manageSubscriptionTapped), for: .touchUpInside) } // @objc函数仅做转发,不使用async throws @objc private func manageSubscriptionTapped() { Task { do { // 从当前控制器的view获取对应的WindowScene,更可靠 guard let windowScene = view.window?.windowScene else { print("无法获取当前WindowScene") return } try await AppStore.showManageSubscriptions(in: windowScene) } catch { print("订阅管理界面展示失败: \(error.localizedDescription)") } } } }
关键修复点说明
- 拆分async逻辑:将
@objc标记的点击事件函数和异步逻辑分离,用Task在主队列执行异步代码,避免Objective-C与Swift异步特性的兼容性问题。 - 统一Target添加时机:在
viewDidLoad中添加按钮点击事件,确保仅绑定一次,避免重复触发。 - 可靠获取WindowScene:通过当前控制器的
view.window?.windowScene获取对应场景,保证操作的是当前活跃的界面场景,避免场景不匹配导致的生命周期异常。
内容的提问来源于stack exchange,提问作者Kevin Alejandro Duron Martínez
相关产品推荐
相关产品推荐

