You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用UITapGestureRecognizer触发BAD ACCESS崩溃,未进入回调求排查

问题分析与解决方案

核心问题:异步方法无法作为手势识别器的Action

UIKit的Target-Action机制不支持直接将async @objc方法作为手势识别器的action。异步方法的底层签名和传统同步@objc方法存在差异,运行时无法正确解析并调用该selector,直接触发BAD ACCESS内存错误,且永远不会进入目标方法。

修复步骤

将异步逻辑包裹在同步的@objc方法内部,通过Task启动异步任务:

// 手势添加代码保持不变
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.goToKeyIdea))
gesture.numberOfTapsRequired = 1
kView.tag = num
kView.isUserInteractionEnabled = true
kView.addGestureRecognizer(gesture)

// 修改后的响应方法
@objc func goToKeyIdea (_ sender: UITapGestureRecognizer) {
    Task {
        let canAccess = await MUser.sharedInstance.canAccessTextSummaries(book: self.data)
        
        if !canAccess {
            self.pay()
        } else {
            let params = [
                "bookId": self.book.subid,
                "UserId": String(MUser.sharedInstance.userId)
            ]
            Flurry.log(eventName: "BookSummaryRead", parameters: params)
            
            await MUser.sharedInstance.incrementRead()
            await MUser.sharedInstance.handleBookStarted(book: self.book)
            
            self.selectedKeyIdea = sender.view?.tag ?? 0
            self.performSegue(withIdentifier: "toText", sender: nil)
        }
    }
}

额外说明

  • 你注释的gesture.view?.tag = num确实无效,因为手势还未添加到kView上,此时gesture.view为nil,无需保留。
  • 关于iOS版本:这不是iOS新版本的突发变更,而是Swift引入async/await(iOS 15+)后,异步方法的签名不符合UIKit Target-Action的要求导致的,属于语言特性与UIKit交互的固有约束。
  • 额外检查:确保持有手势的对象(比如当前视图控制器)没有被提前释放,避免因对象销毁导致的内存访问问题,但本次崩溃的核心原因是异步方法的selector绑定错误。

内容的提问来源于stack exchange,提问作者Rue Vitale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 02:43:27