框架内UITapGestureRecognizer无法触发问题求助
解决CocoaPod框架中UITapGestureRecognizer响应方法不触发的问题
嘿,这其实是个很典型的ARC内存管理坑!你在ViewController的viewDidLoad里创建的Foo实例是个局部变量,当viewDidLoad执行完之后,这个实例就会被自动回收了。而你给手势设置的target正是这个Foo实例,实例都没了,手势触发的时候当然找不到对应的响应方法啦。
下面给你两个靠谱的解决方案:
方案一:让ViewController持有Foo实例(优先推荐)
把Foo从局部变量改成ViewController的类属性,这样它的生命周期就和ViewController绑定在一起,不会被提前释放:
class ViewController: UIViewController { // 声明为类属性,持有Foo实例 private var foo: Foo! override func viewDidLoad() { super.viewDidLoad() foo = Foo() foo.attachTo(view: view) } }
方案二:让Foo内部持有自身引用(谨慎使用)
如果不想让外部代码持有Foo,可以在Foo类里加一个强引用指向自己,不过这种方式要特别注意循环引用的问题:
public class Foo { // 强引用自身,避免被ARC回收 private var selfReference: Foo? public init() { selfReference = self } public func attachTo(view: UIView) { let endpointGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap)) view.addGestureRecognizer(endpointGesture) } @objc private func handleTap() { print("点击事件触发啦!") } }
提醒一下:如果你的Foo类里还持有传入的view对象,这种写法会形成循环引用,导致内存泄漏,所以除非万不得已,还是优先用方案一。
最后再检查两个细节
确保你的响应方法满足这两个要求:
- 必须加上
@objc标记,因为UITapGestureRecognizer是OC体系的API,需要把方法暴露给OC运行时才能识别 - 方法的访问权限至少是
internal,如果用private的话,一定要搭配@objc才能让OC访问到
比如正确的响应方法写法应该是这样:
@objc private func handleTap() { // 这里写你的点击处理逻辑 }
内容的提问来源于stack exchange,提问作者Shrines
相关产品推荐
相关产品推荐

