什么时候在swift代码中使用@objc?

我是新来的迅速,我看到一些方法,如:

@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer) 

我想知道,什么时候使用@objc? 我读了一些文档,但是他们说当你想在Objective-C中调用它时,你应该添加@objc标志

但是,这是一个快捷的私有函数,@obj是做什么的?

私人的意思是它只在Swift中可见。 所以使用@objc在Objective-C中可见。 如果你有一个funcselect一个私人的func快速,这是必需的。

@objc属性使得您的Swift API在Objective-C和Objective-C运行时中可用。

请参阅: https : //developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html

@objc / dynamic

这是为了兼容性:一旦你将Swift文件/代码导入到基于Objective-C的项目中。

如果你想让你的属性/方法被Objective-C代码或类访问,那就使用它。

大多数情况下,当你分类一个Swift类的Objective-C基类时就会发生这种情况。

Swift类或协议必须使用@objc属性标记为可在Objective-C中访问和使用。 这个属性告诉编译器,这段Swift代码可以从Objective-C访问。 如果你的Swift类是一个Objective-C类的后代,编译器会自动为你添加@objc属性。

这里有关于@objc苹果文档。

从Objective-C使用Swift

Swifttypes兼容性

@objc是一个类属性,所以你使用

 @objc public class MyClass 

它将类方法公开给Objective C类,所以如果你的类包含公共函数,你只能使用它

答案很晚,但是这个@objc行为在Swift 4(在Xcode 9中出现,这是在10天前发布的)中略有变化。

在Swift 4中, @objc一些推断情况被删除。 这只是在一些额外的情况下,在Swift编译器推断@objc头之前,它是在Swift 4中不推断。

有关这一变化的Swift进化提议请阅读更多内容

如前所述,通常@objc是将某些方法暴露给Objective-C运行时,这是Swift互操作性语言的一部分。

另一个较晚的答案,但是这个问题上现有的答案都没有真正回答OP的问题,那就是:为什么你需要在private类成员上使用@objc ,如果@objc与Objective-C有交互,并且所讨论的成员是私有的,这意味着即使您的项目中有Objective-C代码,也不应该能够看到该成员?

原因在于,因为许多框架都是用Objective-C编写的,所以需要Objective-C特性来与某些API交互。

例如,假设我想通过DistributedNotificationCenter注册一个通知:

 DistributedNotificationCenter.default.addObserver(self, selector: #selector(somethingHappened(_:)), name: someNotification, object: nil) 

为了这个工作,我们需要能够得到somethingHappened方法的select器。 然而,select器是一个Objective-C的概念,所以如果这个方法对于Objective-C是不可见的,那它就没有select器。 因此,即使该方法是私有的,不应该被任意的外部代码@objc ,为了使用Objective-C编写的DistributedNotification代码能够通过它的select器来调用,它将需要@objc

另一个需要@objc常见情况是支持键值编码(KVC),尤其是在使用KVC和KVO来实现Cocoa绑定的macOS上。 像Cocoa中的许多其他系统一样,KVC在Objective-C中实现,其效果是要求将符合KVC的属性暴露给Objective-C运行时。 有时候,符合KVC的属性是私有的。 一个例子是当你有一个财产影响其他财产:

 @objc private dynamic var originalProperty: String @objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [ #keyPath(originalProperty) ] @objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) } 

在这种情况下,我们实际存储的属性是私有的,但是我们向外部代码公开的依赖属性需要在私有属性更新时发送它的通知。 通过将私有属性标记为@objc ,我们可以很容易地通过设置KVC依赖关系来实现这一点 – 否则,我们必须编写代码来手动发送私有属性的willSetdidSet处理程序中的通知。 此外,通知KVC系统dependentProperty依赖于originalProperty的静态属性需要暴露给Objective-C,以便KVC系统find并调用它,但是它与我们的代码的客户端无关。

此外,macOS应用程序中的视图控制器使用Cocoa Bindings作为实现细节更新其视图中的控件,可能会使某些私有属性符合KVC,以便将这些控件绑定到它们。

所以,正如你所看到的,有些时候方法或者属性可能需要暴露给Objective-C来与框架进行交互,而不一定需要被代码的客户看到。