何时在Swift中使用@objc?

问题描述 投票:74回答:6

在Swift中,我看到一些类似的方法:

@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)

我想知道何时使用@objc?我读了一些文档,但是他们说,当您希望可以在Objective-C中调用它时,应添加@objc标志

但是,这是Swift中的私有函数,@ obj的作用是什么?

ios objective-c swift selector private
6个回答
56
投票

private表示仅在Swift中可见。因此使用@objc在Objective-C中可见。如果您有功能可以快速选择私有功能,则必须使用此功能。

@ 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


49
投票

[另一个较晚的答案,但是关于此问题的现有答案中没有一个能真正回答OP的问题,即:如果@objc存在,为什么您需要在private类成员上使用@objc?与Objective-C的交互,并且所讨论的成员是私有的,这意味着即使您的项目中包含Objective-C代码,它也仍然无法看到该成员?

原因是,因为许多框架都是用Objective-C编写的,所以有时需要Objective-C功能才能与某些API交互。

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

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

为此,我们需要能够获得somethingHappened方法的选择器。但是,选择器是Objective-C的概念,因此,如果该方法对Objective-C不可见,则它没有选择器。因此,即使该方法是私有的并且不应由任意外部代码调用,它也需要一个@objc才能使用Objective-C编写的DistributedNotification代码能够通过其调用选择器。

[需要@objc的另一个常见情况是支持键值编码(KVC),尤其是在使用KVC和KVO来实现可可绑定的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) }

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

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

因此,正如您所看到的,有时可能需要向Objective-C公开方法或属性以与框架进行交互,而不必一定要对代码的客户端可见。


24
投票

@ objc / 动态

出于兼容性考虑:将Swift文件/代码导入基于Objective-C的项目后。

如果希望通过Objective-C代码或类访问属性/方法,请使用该方法。

在大多数情况下,当为Objective-C基类的Swift类子类化时会发生。

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

这里是有关@objc的苹果文档。

Using Swift from Objective-C

Language Interoperability Compatibility

链接已更新:看起来这些链接已被Apple更新。


10
投票

@@ objc是类属性,因此您使用

@objc public class MyClass

它将类的方法公开给Objective C类,因此,只有在您的类包含公共函数的情况下,才使用它。>


7
投票

一个较晚的答案,但是此@objc行为在Swift 4(在Xcode 9中发布,通常在10天前发布)中有所改变。


0
投票

默认情况下,Swift不支持Objective-C互操作性,以避免减少代码库。例如,当您使用Swift语言编写框架时,并且想使用Objective-C代码中的框架时,此功能很有用。

© www.soinside.com 2019 - 2024. All rights reserved.