在Swift中,我看到一些类似的方法:
@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)
我想知道何时使用@objc?我读了一些文档,但他们说要在Objective-C中调用它时,应添加@objc标志
但是,这是Swift中的私有函数,@ obj的作用是什么?
Answers:
private表示仅在Swift中可见。因此使用@objc在Objective-C中可见。如果您有功能可以快速选择私有功能,则必须使用该功能。
@objc属性使您的Swift API在Objective-C和Objective-C运行时中可用。
参见:https : //developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
@objc private func doubleTapGestureRecognized
,同时拥有@objc和private的意义何在?您是说Objective-C类可以覆盖doubleTapGestureRecognized吗?
另一个较晚的答案,但该问题的现有答案都不能真正回答OP的问题,即:为什么要@objc
在private
类成员上使用heck (如果@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
使DistributedNotification
使用Objective-C编写的代码才能通过其选择器调用的方法。
另一个@objc
需要的常见情况是支持键值编码(KVC),尤其是在macOS上,其中KVC和KVO用于实现可可绑定。像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依赖关系轻松地做到这一点-否则,我们必须编写代码以在私有属性willSet
和didSet
处理程序中手动发送通知。另外,通知dependentProperty
依赖于KVC系统的静态属性originalProperty
需要暴露给Objective-C,以便KVC系统找到并调用它,但它与我们代码的客户无关。
另外,使用可可绑定作为实现细节更新其视图中的控件的macOS应用程序中的视图控制器可以使某些私有属性KVC兼容,以便将这些控件绑定到它们。
因此,正如您所看到的,有时可能需要将方法或属性公开给Objective-C以便与框架进行交互,而不必让代码的客户端可见。
@objc /动态
这是为了兼容性:将Swift文件/代码导入基于Objective-C的项目后。
如果希望通过Objective-C代码或类访问属性/方法,请使用该方法。
在大多数情况下,当您将Objective-C基类的Swift类作为子类时,就会发生这种情况。
Swift类或协议必须使用@objc属性标记,才能在Objective-C中访问和使用。该属性告诉编译器可以从Objective-C访问这段Swift代码。如果您的Swift类是Objective-C类的后代,则编译器会自动为您添加@objc属性。
这是关于苹果的文档@objc
。
链接已更新:
看起来这些链接已被Apple更新。
答案很晚,但是@objc
从Swift 4(在Xcode 9中发布,该版本通常在10天前发布)开始,这种行为就有所变化。
在Swift 4中,@objc
删除了的一些推断情况。这只是意味着在某些其他情况下,在@objc
Swift编译器推断出标头之前,Swift 4中并未推断出标头。
在Swift提案中阅读有关此更改的更多信息
如前所述,通常@objc
是将某些方法公开给Objective-C运行时,这是Swift语言互操作性的一部分。
@objc
@objc
向公开声明Objective-C runtime
。让我们看一下#selector
使用Objective-C运行时的Swift功能。在这种情况下,您可以定义您的Swift @objc private func
[更多]
要从Objective-C使用Swift的功能:
NSObject
马克·斯威夫特(Mark Swift):
一种。仅用于@objcMembers
类-公开所有 public
构造函数,字段和方法。也适用于子类
b。@objc
类/枚举/协议(struct除外)[命名类型]
@objc
class(可选)-公开default public init()
。或@objc(<custom_name>)
为类设置自定义名称。@objc
构造函数,字段和方法-有选择地公开它们Swift的方法将在下一个命名中可用:
<swiftName>With<firstArgument>:<secondArgument>:
例如:
public func printHelloWorld(arg1: String, arg2:String)
//is reached through:
[someObject printHelloWorldWithArg1: arg2:];