在Swift 4模式下使用Swift 3 @objc推断是否被弃用?

简而言之,在使用Xcode 9 Beta时,我遇到了以下警告:

在Swift 4模式下使用Swift 3 @objc推断已被弃用。 请解决不推荐使用的@objc推理警告,使用“使用不推荐使用的Swift 3 @objc推断”日志来testing代码,并禁用Swift 3 @objc推理。

经过一番调查,我仍然不知道如何解决这个问题。 我将不胜感激关于如何解决这个问题的任何提示,以及对正在发生的事情的解释。

我的目标是更好地理解我的代码正在发生什么。

通过将我的目标的“Swift 3 @objc Inference”构build设置更改为“Default”,我摆脱了这个警告。

在Xcode9中禁用Swift 3 @objc推理

从这篇文章 :

在Swift 4之前,编译器对Objective-C自动提供了一些Swift声明 。 例如,如果一个子类从NSObject分类,编译器为这些类中的所有方法创buildObjective-C入口点。 该机制被称为@objc推理。

在Swift 4中,这样的自动@objc推断是不推荐的,因为生成所有这些Objective-C入口点代价很高 。 当“Swift 3 @objc Inference”设置为“On”时,它允许旧代码工作。 但是,它会显示需要解决的弃用警告。 build议“解决”这些警告, 并将设置切换到“默认” ,这是新的Swift项目的默认值。

有关更多信息,请参阅此Swift提案 。

– 什么是@objc推理? 到底是怎么回事?

在Swift 3中,编译器推断@objc在许多地方,所以你不必这样做。 换句话说,它确保为你添加@objc

在Swift 4中,编译器不再做这个(尽可能多)。 您现在必须明确添加@objc

默认情况下,如果你有一个Swift 4之前的项目,你会得到这个警告。 在Swift 4项目中,你会得到构build错误。 这是通过SWIFT_SWIFT3_OBJC_INFERENCE构build设置的控制器。 在Swift 4之前的项目中,它被设置为On我build议将其设置为Default (或Off ),这是新项目的默认选项。

转换所有东西需要一些时间,但是因为它是Swift 4的默认值,所以值得这样做。

– 如何停止编译器警告/错误?

有两种方法可以转换你的代码,所以编译器不会抱怨。

一个是在需要暴露给Objective-C运行时的每个函数或variables上使用@objc

 @objc func foo() { } 

另一个是通过Class声明使用@objcMembers 。 这确保了将@objc自动添加到类中的所有函数和variables中。 这是简单的方法,但是它有成本,例如,它可以通过暴露不需要暴露的函数来增加应用程序的大小。

 @objcMembers class Test { } 

– 什么是@objc ,为什么这是必要的?

如果将新的方法或variables引入到Swift类中,将它们标记为@objc它们暴露给Objective-C运行时。 当你有使用你的Swift类的Objective-C代码,或者如果你使用像Selectors这样的Objective-Ctypes的特性时,这是必须的。 例如,target-action模式: button.addTarget(self, action:#selector(didPressButton), for:.touchUpInside)

– 为什么我不标记所有@objc

标记为@objc东西有负面@objc

  • 增加应用程序二进制大小
  • 没有function重载

请记住,这是一个非常高层次的总结,它比我写的更复杂。 我build议阅读实际的提案以获取更多信息。

资料来源:

迁移程序无法识别需要@objc的所有函数推断的Objective-C标记为已弃用的 thunk以帮助您find它们
•build立关于弃用方法的警告
•运行弃用的thunk时控制台消息

在这里输入图像描述

我的两分钱:你可以简单地通过“默认”,而不是“开”。 似乎更贴近苹果的逻辑。

(但所有关于@obj使用的其他评论仍然有效。)

事实上,您将通过禁用Swift 3 @objc推理来摆脱这些警告。 但是,微妙的问题可能会popup。 例如,KVO将停止工作。 这个代码在Swift 3中完美工作:

 for (key, value) in jsonDict { if self.value(forKey: key) != nil { self.setValue(value, forKey: key) } } 

在迁移到Swift 4并将“Swift 3 @objc Inference”设置为默认值后, 我的项目的某些function停止工作 。 我花了一些debugging和研究来find解决scheme。 据我所知,以下是select:

  • 启用“Swift 3 @objc Inference”(仅在您从Swift 3迁移现有项目时才有效) 在这里输入图像描述
  • 将受影响的方法和属性标记为@objc 在这里输入图像描述
  • 使用@objcMembers重新启用整个类的ObjC推理 在这里输入图像描述

重新启用@objc推断会给您留下警告,但这是最快捷的解决scheme。 请注意,它只适用于从早期的Swift版本迁移的项目。 另外两个选项比较单调,需要一些代码挖掘和广泛的testing。

另见https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-inference.md

Swift 3 @objc推理在Swift 4模式下使用Swift 3 @objc推断已经被弃用了。 请解决不推荐使用的@objc推理警告,使用“使用已弃用的Swift 3 @objc推断”日志logging来testing代码,然后通过将“Swift 3 @objc推理”构build设置更改为“Default”作为“XMLParsingURL”目标。

去了

  1. 第一步得到生成设置

  2. searchbuild立设置推理

  3. 更改swift 3 @objc推理默认值

在这里input图像说明