493

简而言之,在使用 Xcode 9 Beta 时,我遇到了以下警告:

不推荐在 Swift 4 模式下使用 Swift 3 @objc 推理。请解决已弃用的@objc 推理警告,在启用“使用已弃用的 Swift 3 @objc 推理”日志记录的情况下测试您的代码,并禁用 Swift 3 @objc 推理。**

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

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

4

12 回答 12

824

我通过将目标的“Swift 3 @objc Inference”构建设置更改为“默认”来消除此警告。

在 Xcode9 中禁用 Swift 3 @objc 推理

这篇文章

在 Swift 4 之前,编译器使一些Swift 声明自动可用于 Objective-C。例如,如果一个从 NSObject 子类化,编译器会为这些类中的所有方法创建 Objective-C 入口点。该机制称为@objc 推理。

在 Swift 4 中,这种自动 @objc 推断已被弃用,因为生成所有这些 Objective-C 入口点的成本很高。当“Swift 3 @objc Inference”设置为“On”时,它允许旧代码工作。但是,它将显示需要解决的弃用警告。建议“修复”这些警告并将设置切换为“默认”,这是新 Swift 项目的默认设置。

另请参阅此 Swift 提案以获取更多信息。

于 2017-06-06T03:21:26.640 回答
272

- 什么是@objc推理?到底是怎么回事?

Swift 3中,编译器@objc会在许多地方进行推断,因此您不必这样做。换句话说,它确保@objc为您添加!

Swift 4中,编译器不再这样做(尽可能多)。您现在必须@objc显式添加。

默认情况下,如果你有一个 Swift 4 之前的项目,你会收到关于这个的警告。在 Swift 4 项目中,您会遇到构建错误。这是通过SWIFT_SWIFT3_OBJC_INFERENCE构建设置控制的。在 Swift 4 之前的项目中,它设置为On. 我建议将其设置为Default(或Off),这现在是新项目的默认选项。

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

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

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

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

@objc func foo() {

}

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

@objcMembers class Test {

}

- 什么是必要的@objc,为什么是必要的?

如果您向 Swift 类引入新方法或变量,请将它们标记为@objc将它们公开给 Objective-C 运行时。当您的 Objective-C 代码使用 Swift 类时,或者,如果您使用 Objective-C 类型的特性(如Selectors. 例如,目标-动作模式: button.addTarget(self, action:#selector(didPressButton), for:.touchUpInside)

- 为什么我不标记所有内容@objc

将某些内容标记为@objc

  • 增加应用程序二进制大小
  • 没有函数重载

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

资料来源:

于 2017-08-03T18:06:26.547 回答
49

Migrator 无法识别所有需要@objc 推断的 Objective-C thunk 标记为已弃用以帮助您找到它们
• 生成有关已弃用方法的警告
• 运行已弃用的 thunk 时的控制台消息

在此处输入图像描述

于 2017-06-14T07:41:49.983 回答
12

我在 "Swift 3 @objc Inference" = "Default" 设置中收到了这个警告。然后我意识到这是为项目设置的——而不是为目标设置的。因此,请确保您的目标中有“默认”设置以消除警告。

于 2018-03-16T22:46:38.103 回答
8

您可以简单地传递给“默认”而不是“开”。似乎更符合苹果的逻辑。

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

于 2017-07-02T09:12:22.833 回答
7

您可以尝试“Pod update”和/或“flutter clean”

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

Objective-C接口设置如下:

ObjectiveC接口设置

于 2019-03-10T12:32:53.257 回答
7

实际上,您可以通过禁用 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

于 2017-09-21T07:56:52.313 回答
7

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

  1. 从左上角开始
  2. 选择项目文件夹图标
  3. 在项目文件夹图标下方选择您的主要项目名称。
  4. 选择右侧的构建设置。
  5. 在 TARGETS 下选择您的项目。
  6. 向下滚动很远(或在搜索文本框中搜索单词推理)

寻找设置

于 2018-11-18T17:52:54.070 回答
2

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

到了

  1. 第一步得到构建设置

  2. 搜索以构建设置推理

  3. 更改 swift 3 @objc 推理默认值

在此处输入图像描述

于 2017-09-28T16:01:53.327 回答
0

除了@wisekiddo 所说的之外,您还可以project.pbxproj通过将 Swift 3 @obj Inference 设置为默认值来修改文件中的构建设置,就像SWIFT_SWIFT3_OBJC_INFERENCE = Default;您的构建风格(即调试和发布)一样,特别是如果您来自其他环境除了 Xcode

于 2019-04-23T10:46:49.430 回答
0

您只需要运行一个测试等到完成,然后转到构建设置,搜索构建设置推理,将 swift 3 @objc 推理更改为(默认)。这就是我所做的一切并且工作完美。

于 2018-12-17T19:59:59.593 回答
0

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

使用 func 调用 @objc

func call(){

foo()

}

@objc func foo() {

}
于 2018-03-26T10:53:35.320 回答