返回

不要在Swift中过度使用@objc,iOS开发者必读!

IOS

就在前几天,我终于把项目迁移到了Swift 2.2。在使用SE-0022建议的#selector语句时,我遇到了一个意料之外的问题:如果在协议扩展中使用#selector,那么这个协议必须添加@objc修饰符。而在此之前,如果想在协议扩展中使用Selector("method:"), 只需简单地将方法标记为@optional即可,不需要任何其他注解。

起初,我认为这是一个小问题,一个简单的解决办法就是给协议添加@objc修饰符。然而,当我在代码库中四处添加@objc时,我开始意识到这样做的潜在影响。@objc本质上是将Objective-C与Swift桥接在一起的胶水。它允许Swift代码与Objective-C代码进行交互,反之亦然。虽然这在某些情况下很有用,但过度使用@objc可能会对代码的性能、可读性和可维护性产生负面影响。

过度使用@objc的潜在问题

过度使用@objc的潜在问题包括:

  • 性能下降: @objc桥接需要额外的开销,这可能会对性能产生负面影响,尤其是当频繁使用@objc时。
  • 可读性降低: @objc注解会使代码变得杂乱且难以阅读。这使得理解和维护代码变得更加困难。
  • 可维护性降低: @objc桥接可能会导致难以发现的错误。例如,如果你忘记给一个应该公开给Objective-C的属性添加@objc修饰符,那么它将无法从Objective-C访问。

替代方案和最佳实践

为了避免过度使用@objc,有几个替代方案和最佳实践可以考虑:

  • 只在需要时使用@objc: 不要仅仅为了使用#selector而给所有内容添加@objc修饰符。只在绝对需要时才使用它,例如,当需要与Objective-C代码进行交互时。
  • 使用Swift原生功能: Swift提供了许多强大的原生功能,可以用来替代@objc。例如,可以使用闭包来代替Objective-C中的块。
  • 考虑使用第三方库: 有许多第三方库可以帮助减少对@objc的使用。例如,RxSwift是一个流行的库,它提供了一个响应式编程框架,可以用来替代Objective-C中的委托和KVO。

在协议扩展中使用#selector

在协议扩展中使用#selector时,有必要给协议添加@objc修饰符。这是因为#selector本质上是一个Objective-C宏,需要@objc桥接才能在Swift中使用。以下是如何在协议扩展中使用#selector的分步指南:

  1. 给协议添加@objc修饰符。
  2. 在协议扩展中声明方法,并使用#selector语法指定方法选择器。
  3. 在协议扩展中实现方法。

示例:

@objc protocol MyProtocol {
    @objc optional func myMethod()
}

extension MyProtocol {
    @objc func myMethod() {
        // 方法实现
    }
}

通过遵循这些指南,iOS开发者可以避免过度使用@objc,并编写更干净、更可维护的Swift代码。