Swift 4.0中创建Selector并调用函数是否有更优Swift风格实现方式?
嘿,你的问题提得很到位!首先得明确:你现在用的#selector写法其实已经是Swift 4+里推荐的现代风格了,并没有过时~不过我们可以聊聊细节优化,以及有没有更贴合Swift编程习惯的实现方式。
1. 先聊聊你当前的写法
你用的#selector(myFunction)是Swift 4引入的类型安全Selector语法,替代了之前容易出错的字符串形式(比如Selector("myFunction:"))——它能在编译阶段就检查函数是否存在,大大降低了运行时崩溃的风险,这本身就是Swift 4+的最佳实践之一。
这里的@objc修饰符是必须的:因为NSStatusBarButton是基于Objective-C的Cocoa API,需要把Swift函数暴露给Objective-C运行时才能被调用。如果不需要用到sender参数,还可以简化代码:
button.action = #selector(myFunction) @objc func myFunction() { print("Hi") }
2. 更贴合Swift风格的闭包回调方式
如果你觉得Target-Action模式太有“Objective-C味儿”,可以给NSStatusBarButton写一个扩展,让它支持闭包回调——这种方式更符合Swift的闭包编程习惯,不用额外写@objc函数,代码逻辑也更集中:
extension NSStatusBarButton { private struct AssociatedKeys { static var actionClosure = "ActionClosure" } // 给按钮添加闭包属性 var actionClosure: (() -> Void)? { get { return objc_getAssociatedObject(self, &AssociatedKeys.actionClosure) as? () -> Void } set { objc_setAssociatedObject(self, &AssociatedKeys.actionClosure, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) // 将按钮自身设为target,绑定内部转发函数 self.target = self self.action = #selector(handleAction) } } // 内部转发用的@objc函数,对外不可见 @objc private func handleAction() { actionClosure?() } }
使用的时候就非常简洁了:
button.actionClosure = { print("Hi") }
总结
- 你当前的
#selector写法是标准且安全的,完全没有过时; - 如果想要更“Swift化”的实现,闭包扩展是很好的选择,既保持了类型安全,又让代码更紧凑。
内容的提问来源于stack exchange,提问作者Jared Pieniazek
相关产品推荐
相关产品推荐

