简而言之,在使用 Xcode 9 Beta 时,我遇到了以下警告:
不推荐在 Swift 4 模式下使用 Swift 3 @objc 推理。请解决已弃用的@objc 推理警告,在启用“使用已弃用的 Swift 3 @objc 推理”日志记录的情况下测试您的代码,并禁用 Swift 3 @objc 推理。**
经过一番研究,我仍然不知道如何解决这个问题。我将非常感谢有关如何解决此问题的任何提示以及对正在发生的事情的解释。
我的目标是更好地理解我的代码发生了什么。
我通过将目标的“Swift 3 @objc Inference”构建设置更改为“默认”来消除此警告。
https://i.stack.imgur.com/7JcQ5.png
从 this article:
在 Swift 4 之前,编译器使一些 Swift 声明自动可用于 Objective-C。例如,如果一个从 NSObject 子类化,编译器会为这些类中的所有方法创建 Objective-C 入口点。该机制称为@objc 推理。在 Swift 4 中,这种自动 @objc 推断已被弃用,因为生成所有这些 Objective-C 入口点的成本很高。当“Swift 3 @objc Inference”设置为“On”时,它允许旧代码工作。但是,它将显示需要解决的弃用警告。建议“修复”这些警告并将设置切换为“默认”,这是新 Swift 项目的默认设置。
另请参阅 this Swift proposal 了解更多信息。
- 什么是@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() {
}
另一种是通过 Class
声明使用 @objcMembers
。这确保自动将 @objc
添加到类中的ALL函数和变量。这是一种简单的方法,但它也有代价,例如,它可以通过公开不需要公开的函数来增加应用程序的大小。
@objcMembers class Test {
}
- 什么是@objc,为什么它是必要的?
如果您向 Swift 类引入新方法或变量,将它们标记为 @objc
会将它们公开给 Objective-C 运行时。当您的 Objective-C 代码使用您的 Swift 类时,或者如果您使用像 Selectors
这样的 Objective-C 类型的功能,这是必要的。例如,目标-动作模式:button.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
@objc
并不意味着动态调度,Swift 可以自由使用静态或虚拟调度(并可能因此执行不同的代码)。 dynamic
关键字是强制 Swift 使用动态调度所必需的。
@objc
贬低我们必须使用什么?
On
离开 SWIFT_SWIFT3_OBJC_INFERENCE
。转换为 Swift 4。然后处理 @objc
的东西。为简单起见,请遵循基本规则:如果在 Objc-C 代码中使用 Swift 类(通过桥接头),则使用 @objcMembers
,否则,一一添加 @objc
。只需使用 Xcode 搜索即可确定是否从任何 .m
文件调用了 Swift 类。这应该使转换相对轻松。
@objc
发生了变化,然后然后决定修复项目并使其保持不变。
Migrator 无法识别所有需要 @objc 推断的 Objective-C thunk 标记为已弃用以帮助您找到它们 • 生成有关已弃用方法的警告 • 运行已弃用的 thunk 时的控制台消息
https://i.stack.imgur.com/ItjoY.png
我在 "Swift 3 @objc Inference" = "Default" 设置中收到了这个警告。然后我意识到这是为项目设置的——而不是为目标设置的。因此,请确保您的目标中有“默认”设置以消除警告。
您可以简单地传递给“默认”而不是“开”。似乎更符合苹果的逻辑。
(但关于使用 @obj
的所有其他评论仍然有效。)
实际上,您可以通过禁用 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
我是一个偶尔的 iOS 开发人员(很快就会更多),但我仍然找不到其他答案所指导的设置(因为我没有答案显示的钥匙串项目),所以现在我找到了我想我可能只是将这个快照添加到突出显示的位置,您需要单击并找到它们。
从左上角开始 选择项目文件夹图标 在项目文件夹图标下方选择您的主项目名称。选择右侧的构建设置。在 TARGETS 下选择您的项目。向下滚动很远(或在搜索文本框中搜索单词推断)
https://i.stack.imgur.com/S20lw.png
您可以尝试“Pod update”和/或“flutter clean”
我还在 xcode 中设置了这个设置。
Objective-C接口设置如下:
https://i.stack.imgur.com/OZLDb.png
Swift 3 @objc 推理 在 Swift 4 模式下使用 Swift 3 @objc 推理已被弃用。请解决已弃用的@objc 推理警告,在启用“使用已弃用的 Swift 3 @objc 推理”日志记录的情况下测试您的代码,然后通过将“XMLParsingURL”的“Swift 3 @objc 推理”构建设置更改为“默认”来禁用推理目标。
到了
第一步得到 Build Setting Search in to Build Setting Inference change swift 3 @objc Inference Default
在 Swift 4 模式下使用 Swift 3 @objc 推理已被弃用?
使用 func 调用 @objc
func call(){
foo()
}
@objc func foo() {
}
您只需要运行一个测试等到完成,然后转到构建设置,搜索构建设置推理,将 swift 3 @objc 推理更改为(默认)。这就是我所做的一切并且工作完美。
除了@wisekiddo 所说的之外,您还可以通过将 Swift 3 @obj Inference 设置为默认值(如 SWIFT_SWIFT3_OBJC_INFERENCE = Default;
)来修改 project.pbxproj
文件中的构建设置,以适应您的构建风格(即调试和发布),特别是如果您re 来自 Xcode 以外的其他环境
@objc
推理已被弃用。请解决已弃用的@objc
推理警告,使用“使用已弃用的 Swift 3@objc
推理”日志记录已启用,并禁用 Swift 3@objc
推理。”知道在哪里启用上述 Swift 3@objc
推理日志记录吗?