Swift中能否返回@objc函数?Selector适配技术问询
如何在Swift中为UITapGestureRecognizer绑定动态闭包(替代@objc闭包方案)
嗨,直接返回@objc标记的闭包确实走不通——Objective-C的Selector机制依赖于类的方法签名,它只能识别属于某个类实例的方法,而独立的闭包并没有和类的方法表关联,所以#selector根本找不到它。不过咱们有几个靠谱的替代方案,完美实现你想要的“给不同IndexPath绑定不同点击逻辑”的需求:
方案一:给UITapGestureRecognizer扩展关联对象存储闭包
这是最灵活的方案,相当于给每个手势对象绑定一个专属闭包,不用在ViewController里写一堆重复的@objc方法:
import ObjectiveC // 定义一个唯一的关联对象Key(用来区分不同的关联属性) private var TapGestureClosureKey = 0 extension UITapGestureRecognizer { // 用关联对象存储闭包 private var tapClosure: (() -> Void)? { get { return objc_getAssociatedObject(self, &TapGestureClosureKey) as? () -> Void } set { objc_setAssociatedObject(self, &TapGestureClosureKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } // 自定义初始化方法,直接传入闭包 convenience init(tapHandler: @escaping () -> Void) { self.init(target: self, action: #selector(triggerTapClosure)) self.tapClosure = tapHandler } // 通用的@objc处理方法,触发时调用存储的闭包 @objc private func triggerTapClosure() { tapClosure?() } }
使用方式
直接把你原来的getFunction返回的闭包传进去就行:
// 给目标视图添加手势 let tapGesture = UITapGestureRecognizer(tapHandler: getFunction(for: index)) yourTargetView.addGestureRecognizer(tapGesture)
方案二:通过Tag传递IndexPath信息
如果你的场景比较简单,也可以用视图的tag来传递IndexPath的信息,然后在统一的@objc方法里处理逻辑:
// 给视图设置Tag(这里用row+section*1000来区分不同section,避免tag重复) yourTargetView.tag = indexPath.row + indexPath.section * 1000 // 创建手势,指向统一的处理方法 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapWithIndexPath(_:))) yourTargetView.addGestureRecognizer(tapGesture) // 实现@objc处理方法 @objc private func handleTapWithIndexPath(_ gesture: UITapGestureRecognizer) { guard let tag = gesture.view?.tag else { return } // 解析回IndexPath let section = tag / 1000 let row = tag % 1000 let targetIndexPath = IndexPath(row: row, section: section) // 调用你的闭包逻辑 getFunction(for: targetIndexPath)() }
这个方案适合不需要太复杂动态逻辑的场景,但要注意Tag的唯一性,避免不同视图的Tag冲突。
为什么直接返回@objc闭包不可行?
再啰嗦一句:Objective-C运行时的Selector是基于类方法表的,它需要找到某个类的实例上的具体方法。闭包是Swift的独立代码块,没有被注册到任何类的方法表里,所以#selector根本无法定位到它——这也是为什么你原来的写法会报错的核心原因。
内容的提问来源于stack exchange,提问作者zoecarver
相关产品推荐
相关产品推荐

