不推荐在Swift 4模式下使用Swift 3 @objc推理?

时间:2017-06-05 23:49:06

标签: swift swift4 xcode9-beta

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

  

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

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

我的目标是更好地了解我的代码所发生的事情。

12 个答案:

答案 0 :(得分:769)

我通过更改" Swift 3 @objc Inference"来摆脱这个警告。将我的目标设置为"默认"。

Disable Swift 3 @objc inference in Xcode9

来自this article

  

在Swift 4之前,编译器为Objective-C 自动提供了一些 Swift声明。例如,如果一个子类来自NSObject,则编译器为这些类中的所有方法创建了Objective-C入口点。该机制称为@objc推理。

     

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

请参阅this Swift proposal了解更多信息。

答案 1 :(得分:255)

- 什么是@objc推断?发生了什么事?

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

Swift 4中,编译器不再执行此操作(同样多)。您现在必须明确添加@objc

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

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

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

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

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

@objc func foo() {

}

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

@objcMembers class Test {

}

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

如果向Swift类引入新方法或变量,将它们标记为@objc会将它们暴露给Objective-C运行时。当您拥有使用Swift类的Objective-C代码时,或者如果您使用的是Selectors等Objective-C类型的功能时,这是必需的。例如,目标 - 行动模式: button.addTarget(self, action:#selector(didPressButton), for:.touchUpInside)

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

标记为@objc时会出现负面影响:

  • 增加应用程序二进制文件大小
  • 无功能超载

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

来源:

答案 2 :(得分:47)

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

enter image description here

答案 3 :(得分:8)

您可以简单地传递到“默认”而不是“开启”。似乎更符合Apple逻辑。

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

答案 4 :(得分:8)

我和#34; Swift 3 @objc Inference" ="默认"设置。然后我意识到这是为项目设定的 - 而不是针对目标。因此,请确保您拥有"默认"在目标中设置以消除警告。

答案 5 :(得分:7)

实际上,您可以通过禁用Swift 3 @objc推理来消除这些警告。 但是,可能会出现微妙的问题。例如,KVO将停止工作。 这段代码在Swift 3下完美运行:

for (key, value) in jsonDict {
    if self.value(forKey: key) != nil {
        self.setValue(value, forKey: key)
    }
}

迁移到Swift 4后,设置" Swift 3 @objc推理"默认情况下,我项目的某些功能停止工作。 我花了一些调试和研究来找到解决方案。 根据我的最佳知识,以下是选项:

  • 启用" Swift 3 @objc推理" (仅当您从Swift 3迁移现有项目时才有效)enter image description here
  • 将受影响的方法和属性标记为@objc enter image description here
  • 使用@objcMembers enter image description here重新启用整个班级的ObjC推理

重新启用@objc推理会给您留下警告,但它是最快的解决方案。请注意,它仅适用于从早期Swift版本迁移的项目。 其他两个选项更繁琐,需要进行一些代码挖掘和广泛的测试。

另见https://github.com/apple/swift-evolution/blob/master/proposals/0160-objc-inference.md

答案 6 :(得分:2)

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

到了

  1. 第一步获得了Build Setting

  2. 搜索构建设置推理

  3. 更改swift 3 @objc Inference Default

  4. enter image description here

答案 7 :(得分:2)

我偶尔是iOS开发人员(不久以后会更多),但我仍然找不到其他答案指导的设置(因为我没有答案显示的那个Keychain项),所以现在我发现了我以为我可能只是将快照添加了需要单击并找到的突出显示的位置。

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

Finding the setting

答案 8 :(得分:1)

您可以尝试“ Pod更新”和/或“干净”

我也在xcode中设置了此设置。

Objective-C界面设置如下:

ObjectiveC interface setting

答案 9 :(得分:0)

  

不赞成在Swift 4模式下使用Swift 3 @objc推理?

使用func调用@objc

func call(){

foo()

}

@objc func foo() {

}

答案 10 :(得分:0)

您所要做的只是测试直到完成,然后转到Build Setting,搜索到Build Setting Inference, 将swift 3 @objc推断更改为(默认)。这就是我所做的一切并且完美地完成了。

答案 11 :(得分:0)

除了@wisekiddo所说的那样,您还可以通过将Swift 3 @obj Inference的默认设置(例如project.pbxproj)设置为SWIFT_SWIFT3_OBJC_INFERENCE = Default;来修改Application.UseSignalR(R => MapperMethodInfo.MakeGenericMethod(H).Invoke(R, new object [] { Path })); 文件中的构建设置(例如,调试和版本),特别是如果您来自Xcode以外的其他环境