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

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

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

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


当前回答

事实上,你可以通过禁用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更改为(默认)。我就是这么做的,而且效果很好。

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

使用func调用@objc

func call(){

foo()

}

@objc func foo() {

}

你可以简单地传递到“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

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