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

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

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

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

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

103993 次浏览

我通过更改“Swift 3 @objc inference”来摆脱这个警告;建立我的目标设置为“默认”。

Disable Swift 3 @objc inference in Xcode9

这篇文章:

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

在Swift 4中,这种自动的@objc推断被弃用了,因为生成所有这些Objective-C入口点的成本很高。当“Swift推论”;设置为“on”,它允许旧代码工作。但是,它将显示需要处理的弃用警告。建议使用"fix"这些警告和将设置切换为“默认”;,这是新Swift项目的默认值。

更多信息请参考斯威夫特的提议

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

enter image description here

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

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

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

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

Swift 4中,编译器不再这样做。现在必须显式地添加@objc

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

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

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

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

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

@objc func foo() {


}

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

@objcMembers class Test {


}

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

如果你在Swift类中引入了新的方法或变量,将它们标记为@objc将它们暴露给Objective-C运行时。当你有Objective-C代码使用你的Swift类,或者,如果你正在使用Objective-C类型的特性,如Selectors,这是必要的。例如,目标-操作模式: button.addTarget(self, action:#selector(didPressButton), for:.touchUpInside) < / p >

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

标记为@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迁移现有项目)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

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

到了

  1. 第一步是构建设置

  2. 搜索到构建设置推理

  3. change swift 3 @objc Inference默认值

enter image description here

我有这个警告“Swift 3 @objc Inference”=“默认”设置。然后我意识到这是为项目设置的,而不是为目标设置的。所以,确保你在目标中有“默认”设置,以消除警告。

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

使用func调用@objc

func call(){


foo()


}


@objc func foo() {


}

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

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

查找设置

你所需要的只是运行一个测试,等待完成,之后进入构建设置,搜索到构建设置推理, 将swift 3 @objc Inference更改为(默认)。

您可以尝试“Pod更新”和/或“颤振清理”

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

Objective-C界面设置如下:

ObjectiveC接口设置

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