简单地说,在使用Xcode 9 Beta时,我遇到了以下警告:

不建议在Swift 4模式中使用Swift 3 @objc推断。请解决已弃用的@objc推断警告,测试代码时启用“使用已弃用的Swift 3 @objc推断”日志记录,并禁用Swift 3 @objc推断。**

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

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


当前回答

我是一个偶尔的iOS开发者(很快就会更多),但我仍然无法找到其他答案所引导的设置(因为我没有答案所显示的钥匙链项目),所以现在我找到了它,我想我可以添加这个快照,突出显示你需要点击并找到的位置。

从左上方开始 选择项目文件夹图标 选择项目文件夹图标下面的主项目名称。 在右侧选择Build Settings。 在TARGETS下面选择您的项目。 向下滚动(或在搜索中搜索单词推理) 文本框)

其他回答

Migrator不能识别所有需要@objc的函数 推断的Objective-C坦克标记为已弃用,以帮助您找到它们 •构建关于已弃用方法的警告 •运行过时的坦克时控制台消息

我摆脱了这个警告通过改变“Swift 3 @objc推断”构建设置我的目标为“默认”。

从这篇文章中:

Before Swift 4, the compiler made some Swift declarations automatically available to Objective-C. For example, if one subclassed from NSObject, the compiler created Objective-C entry points for all methods in such classes. The mechanism is called @objc inference. In Swift 4, such automatic @objc inference is deprecated because it is costly to generate all those Objective-C entry points. When "Swift 3 @objc Inference" setting is set to "On", it allows the old code to work. However, it will show deprecation warnings that need to be addressed. It is recommended to "fix" these warnings and switch the setting to "Default", which is the default for new Swift projects.

更多信息请参考Swift提案。

在@wisekiddo所说的之上,您还可以在项目中修改您的构建设置。通过将SWIFT_SWIFT3_OBJC_INFERENCE = default设置为SWIFT_SWIFT3_OBJC_INFERENCE = default;对于你的构建风格(即调试和发布),特别是如果你来自Xcode以外的其他环境

Swift 3 @objc推断 不建议在Swift 4模式中使用Swift 3 @objc推断。请解决已弃用的@objc推断警告,测试您的代码,启用“使用已弃用的Swift 3 @objc推断”日志记录,然后通过将“Swift 3 @objc推断”构建设置更改为“默认”的“XMLParsingURL”目标来禁用推断。

到了

第一步是构建设置 搜索到构建设置推理 change swift 3 @objc Inference默认值

在这里输入图像描述

什么是@objc推理?这是怎么回事?

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

在Swift 4中,编译器不再这样做了。现在必须显式地添加@objc。

默认情况下,如果你有一个swift 4之前的项目,你会得到关于这个的警告。在Swift 4项目中,你会得到构建错误。这是通过SWIFT_SWIFT3_OBJC_INFERENCE构建设置来控制的。在swift 4之前的项目中,这被设置为On。我建议将此设置为默认(或关闭),这是现在新项目的默认选项。

转换所有内容需要一些时间,但由于这是Swift 4的默认设置,所以值得这么做。

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

有两种方法可以转换代码,这样编译器就不会报错。

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

@objc func foo() {

}

另一种方法是通过Class声明使用@objcMembers。这确保自动将@objc添加到类中的所有函数和变量中。这是一种简单的方法,但它有代价,例如,它会通过公开不需要公开的函数来增加应用程序的大小。

@objcMembers class Test {

}

@objc是什么?为什么需要它?

如果你向Swift类中引入了新的方法或变量,将它们标记为@objc,就会将它们暴露给Objective-C运行时。当你有Objective-C代码使用你的Swift类,或者,如果你使用Objective-C类型的功能,如选择器,这是必要的。例如,目标-操作模式: 按钮。addTarget(self, action:#selector(didPressButton), for:.touchUpInside)

-为什么我不把所有东西都标记为@objc?

有一些带有@objc标记的负号:

增加应用程序二进制大小 无函数重载


请记住,这是一个非常高级的总结,它比我写的要复杂得多。我建议你阅读提案以获得更多信息。

来源:

https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-inference.md https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/WritingSwiftClassesWithObjective-CBehavior.html#//apple_ref/doc/uid/TP40014216-CH5-ID86