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

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

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

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


我摆脱了这个警告通过改变“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提案。


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


你可以简单地传递到“default”而不是“ON”。似乎更符合苹果的逻辑。

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


什么是@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


事实上,你可以通过禁用Swift 3 @objc Inference来消除这些警告。 然而,可能会出现一些微妙的问题。例如,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”设置为默认值后,我的项目的某些功能停止了工作。 我花了一些调试和研究来找到解决方案。 据我所知,有以下几种选择:

启用“Swift 3 @objc Inference”(仅适用于从Swift 3迁移现有项目) 将受影响的方法和属性标记为@objc 使用@objcMembers为整个类重新启用ObjC推断

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

参见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推断”日志记录,然后通过将“Swift 3 @objc推断”构建设置更改为“默认”的“XMLParsingURL”目标来禁用推断。

到了

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

在这里输入图像描述


我有这个警告“Swift 3 @objc Inference”=“默认”设置。然后我意识到这是为项目设置的,而不是为目标设置的。所以,确保你在目标中有“默认”设置,以消除警告。


在Swift 4模式下使用Swift 3 @objc推断已弃用?

使用func调用@objc

func call(){

foo()

}

@objc func foo() {

}

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

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


你只需要运行一个测试,等待完成,之后进入构建设置,搜索到构建设置推理, 将swift 3 @objc Inference更改为(默认)。我就是这么做的,而且效果很好。


您可以尝试“Pod更新”和/或“颤振清理”

我也在xcode中设置了这个设置。

Objective-C界面设置如下:


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