Swift中什么时候使用@objc?

ecr0jaav  于 2023-08-02  发布在  Swift
关注(0)|答案(6)|浏览(142)

在Swift中,我看到了一些方法,比如:

@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)

字符串
我想知道,什么时候使用@objc?我读了一些文档,但是他们说当你想在Objective-C中调用它时,你应该添加@objc标志
但是,这是Swift中的私有函数,@obj是做什么的?

3ks5zfa0

3ks5zfa01#

另一个迟到的答案,但关于这个问题的现有答案都没有真正回答OP的问题,即:如果@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用于实现可可绑定。像可可中的许多其他系统一样,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) }


在这种情况下,我们实际存储的属性是私有的,但是依赖属性(我们 * 公开给外部代码)需要在私有属性更新时发送通知。通过将private属性标记为@objc,我们可以通过设置KVC依赖性来轻松完成这一点,否则,我们必须编写代码来手动发送private属性的willSetdidSet处理程序中的通知。此外,通知KVC系统dependentProperty依赖于originalProperty的静态属性需要暴露给Objective-C,以便KVC系统找到它并调用它,但它与我们代码的客户端无关。
此外,macOS应用程序中的视图控制器使用可可Bindings作为实现细节来更新其视图中的控件,可能会使某些私有属性符合KVC标准,以便将这些控件绑定到它们。
因此,正如你所看到的,有时候,一个方法或属性可能需要公开给Objective-C,以便与框架交互,而不一定需要对代码的客户端可见。

5cnsuln7

5cnsuln72#

private表示它只在Swift中可见。所以使用@objc在Objective-C中可见。如果你有一个函数来选择swift中的私有函数,它是必需的。
@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

nzk0hqpo

nzk0hqpo3#

@objc/动态

为了兼容性:一旦你将Swift文件/代码导入到基于Objective-C的项目中。
如果你希望你的属性/方法被Objective-C代码或类访问,请使用它。
大多数情况下,它发生在你从Objective-C基类中派生Swift类的时候。
Swift类或协议必须标记有**@objc**属性,才能在Objective-C中访问和使用。这个属性告诉编译器这段Swift代码可以从Objective-C访问。如果Swift类是Objective-C类的后代,编译器会自动为你添加@objc属性。
这里是苹果的文档,上面写着@objc
Using Swift from Objective-C
语言互操作性兼容性

链接更新:

看来苹果已经更新了链接。

dtcbnfnu

dtcbnfnu4#

@objc是一个类属性,因此使用

@objc public class MyClass

字符串
它将类的方法公开给ObjectiveC类,所以只有当类包含公共函数时才使用它

nzrxty8p

nzrxty8p5#

这是一个迟来的答案,但这种@objc行为在Swift 4(在Xcode 9中出现,通常在10天前发布)中略有变化。
在Swift 4中,删除了@objc的一些推理情况。这只是意味着在一些额外的情况下,在Swift编译器推断@objc头之前,它在Swift 4中没有推断。
阅读有关this change的Swift演化提案
如前所述,一般来说,@objc是将某些方法公开给Objective-C运行时,这是Swift语言互操作性的一部分。

a6b3iqyw

a6b3iqyw6#

Swift @objc vs @objcMembers

@objc将声明公开给Objective-C runtimeAbout(https://stackoverflow.com/a/66269619/4770877)。让我们来看看Swift的#selectorAbout(https://stackoverflow.com/a/59236656/4770877)特性,以使用Objective-C运行时。在本例中,您可以定义Swift @objc private funcMore(https://stackoverflow.com/a/60954443/4770877)
从Objective-C使用Swift的函数:

  1. Swift的类应该从**NSObject**扩展
  2. Mark Swift:
    a. @objcMembersclassonly -暴露所有public构造函数字段方法。它也适用于子类
    B. @objcclass/enum/protocol(除struct外)Named Type(https://stackoverflow.com/a/59219141/4770877)
  • @objcclass(可选)-公开defaultpublic init()。或者@objc(<custom_name>)来设置类的自定义名称。
  • @objc构造函数字段方法-选择性地公开它们

Swift的方法将在下一个命名中可用:

<swiftName>With<firstArgument>:<secondArgument>:

字符串
举例来说:

public func printHelloWorld(arg1: String, arg2:String)
//is reached through: 
[someObject printHelloWorldWithArg1: arg2:];


@objc and dynamic(https://stackoverflow.com/a/60937714/4770877)的

相关问题