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

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

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

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


当前回答

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

其他回答

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

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

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

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

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

你只需要运行一个测试,等待完成,之后进入构建设置,搜索到构建设置推理, 将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