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

不推荐在Swift 4模式下使用Swift 3@objc推理?,swift,swift4,xcode9-beta,Swift,Swift4,Xcode9 Beta,简单地说,在使用Xcode 9 Beta时,我遇到了以下警告: 不推荐在Swift 4模式下使用Swift 3@objc推理。请解决不推荐使用的@objc推理警告,在启用“使用不推荐使用的Swift 3@objc推理”日志记录的情况下测试代码,并禁用Swift 3@objc推理** 经过一些研究,我仍然不知道如何解决这个问题。 我将非常感谢任何关于如何解决这个问题的提示,以及对正在发生的事情的解释 我的目标是更好地理解代码中发生的事情 我将目标的“Swift 3@objc推理”构建设置更改为“D

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

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

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


我的目标是更好地理解代码中发生的事情

我将目标的“Swift 3@objc推理”构建设置更改为“Default”,从而消除了此警告

发件人:

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

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


有关更多信息,请参阅。

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

您只需传递到“默认”而不是“打开”。似乎更符合苹果的逻辑

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

-什么是
@objc
推理?发生了什么事? 在
swift3
中,编译器在许多地方推断出
@objc
,这样您就不必这样做了。换句话说,它确保为您添加
@objc

swift4
中,编译器不再执行此操作(同样多)。现在必须显式添加
@objc

默认情况下,如果您有一个Swift 4之前的项目,您将收到关于此的警告。在Swift 4项目中,您将获得生成错误。这是通过
SWIFT\u SWIFT3\u OBJC\u推理
build设置控制的。在Swift 4之前的项目中,此设置为上的
我建议将其设置为
Default
(或
Off
),这是新项目的默认选项。

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

-如何停止编译器警告/错误? 有两种方法可以转换代码,这样编译器就不会抱怨了

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

@objc func foo() {

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

@objcMembers class Test {

}

-什么是
@objc
,为什么需要它? 如果将新方法或变量引入Swift类,则将它们标记为
@objc
将向Objective-C运行时公开它们。当您有使用Swift类的Objective-C代码时,或者如果您使用的是Objective-C-type功能,如
选择器
,这是必需的。例如,目标操作模式:
button.addTarget(self,action:#选择器(didPressButton),for:.touchupind)

-为什么我不把所有东西都标记为objc
? 将某物标记为
@objc
会带来负面影响:

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

请记住,这是一个非常高层次的总结,它比我写的更复杂。我建议阅读实际提案以了解更多信息

资料来源:

实际上,您可以通过禁用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迁移现有项目时有效)
  • 将受影响的方法和属性标记为@objc
  • 使用@objcMembers为整个类重新启用ObjC推断
重新启用@objc推理会给您留下警告,但这是最快的解决方案。请注意,它仅适用于从早期Swift版本迁移的项目。 另外两个选项更繁琐,需要一些代码挖掘和大量测试

另请参见Swift 3@objc推理 不推荐在Swift 4模式下使用Swift 3@objc推理。请解决不推荐使用的@objc推理警告,在启用“使用不推荐使用的Swift 3@objc推理”日志记录的情况下测试代码,然后通过将“XMLParsingURL”目标的“Swift 3@objc推理”生成设置更改为“Default”来禁用推理

到达终点

  • 第一步是构建设置

  • 搜索以生成设置推断

  • func call(){
    
    foo()
    
    }
    
    @objc func foo() {
    
    }