ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

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

我并没有真正从警告消息中得到哪个对象导致它。 Xcode 根本没有说明该对象在哪一行。任何建议如何找出此警告的来源?

C
Community

我通过将目标的“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 了解更多信息。


谢谢叶夫根尼。这是一个长期的解决方案吗?
@DaleK 是的,我相信是的。根据我在回答中提到的 Swift 提议,不推荐使用 objc 推断。 “Swift 3 objc Inference”设置仅存在于从旧版本 Swift 迁移的项目中。如果创建一个新项目,则该设置不再存在,这意味着 objc 推理已关闭。建议解决任何 objc 推理警告并将其设置为“关闭”。
XCode 中的信息消息表明:“在 Swift 4 模式下使用 Swift 3 @objc 推理已被弃用。请解决已弃用的 @objc 推理警告,使用“使用已弃用的 Swift 3 @objc推理”日志记录已启用,并禁用 Swift 3 @objc 推理。”知道在哪里启用上述 Swift 3 @objc 推理日志记录吗?
@courteouselk,根据 Swift 提案,可以将 SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT 环境变量设置为 1 到 3 的值,以查看日志中 Objective-C 入口点的使用情况。
只需添加 - 您需要为所有构建标记执行此操作,而不仅仅是项目。
J
John Topley

- 什么是@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 贬低我们必须使用什么?
@Stefan 是的,可能有很多需要转换的地方。把它分成几个阶段。在 On 离开 SWIFT_SWIFT3_OBJC_INFERENCE。转换为 Swift 4。然后处理 @objc 的东西。为简单起见,请遵循基本规则:如果在 Objc-C 代码中使用 Swift 类(通过桥接头),则使用 @objcMembers,否则,一一添加 @objc。只需使用 Xcode 搜索即可确定是否从任何 .m 文件调用了 Swift 类。这应该使转换相对轻松。
@DaleK 这应该被接受的答案。抑制警告并使事情像在 Swift 3 中一样工作是一种选择,但恕我直言,这不是最好的选择。重要的是要了解为什么 Swift 4 中的 @objc 发生了变化,然后然后决定修复项目并使其保持不变。
感谢您的简短解释
H
Hassan Taleb

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

https://i.stack.imgur.com/ItjoY.png


那么我应该如何处理@objc?去掉它?别管它?我已经删除了。我收到了这些警告,所以我必须添加它们?在第 3 步中我应该这样做吗?
在 func 之前添加 @objc
第 3 步是什么?你可以添加一些描述:)
就我而言,我收到了这个警告,但没有指向任何代码。有两种标记为@objc 的方法,它们似乎是唯一需要它的方法。我将其更改为默认值,但在编译期间仍然收到警告。
D
Dmitry

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


即使在项目设置中更改为默认值后,我还是浪费了 20 分钟来解决错误。您准确地指出了它也需要在目标中进行更改。
H
Hemant Singh Rathore

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

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


K
Karoly Nyisztor

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


r
raddevus

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

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

https://i.stack.imgur.com/S20lw.png


S
Siong Thye Goh

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

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

Objective-C接口设置如下:

https://i.stack.imgur.com/OZLDb.png


P
Praveen Kumar

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

enter image description here


P
Pang

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

使用 func 调用 @objc

func call(){

foo()

}

@objc func foo() {

}

A
Acasey

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


D
DaveNOTDavid

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