简单地说,在使用Xcode 9 Beta时,我遇到了以下警告:
不建议在Swift 4模式中使用Swift 3 @objc推断。请解决已弃用的@objc推断警告,测试代码时启用“使用已弃用的Swift 3 @objc推断”日志记录,并禁用Swift 3 @objc推断。**
经过一番研究,我仍然不知道如何解决这个问题。 我将非常感谢任何关于如何解决这个问题的提示,以及对正在发生的事情的解释。
我的目标是更好地理解我的代码发生了什么。
简单地说,在使用Xcode 9 Beta时,我遇到了以下警告:
不建议在Swift 4模式中使用Swift 3 @objc推断。请解决已弃用的@objc推断警告,测试代码时启用“使用已弃用的Swift 3 @objc推断”日志记录,并禁用Swift 3 @objc推断。**
经过一番研究,我仍然不知道如何解决这个问题。 我将非常感谢任何关于如何解决这个问题的提示,以及对正在发生的事情的解释。
我的目标是更好地理解我的代码发生了什么。
当前回答
我有这个警告“Swift 3 @objc Inference”=“默认”设置。然后我意识到这是为项目设置的,而不是为目标设置的。所以,确保你在目标中有“默认”设置,以消除警告。
其他回答
在@wisekiddo所说的之上,您还可以在项目中修改您的构建设置。通过将SWIFT_SWIFT3_OBJC_INFERENCE = default设置为SWIFT_SWIFT3_OBJC_INFERENCE = default;对于你的构建风格(即调试和发布),特别是如果你来自Xcode以外的其他环境
什么是@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更改为(默认)。我就是这么做的,而且效果很好。
事实上,你可以通过禁用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 Inference”=“默认”设置。然后我意识到这是为项目设置的,而不是为目标设置的。所以,确保你在目标中有“默认”设置,以消除警告。