何时在swift代码中使用@objc?

时间:2015-06-12 04:03:55

标签: ios swift

我是swift的新手,我看到了一些方法,如:

andThen

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

但是,这是swift中的私有函数,@ obj做了什么?

6 个答案:

答案 0 :(得分:45)

私人意味着它只在Swift中可见。 所以使用@objc在Objective-C中可见。 如果你有一个func来选择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

答案 1 :(得分:41)

另一个迟到的答案,但这个问题的现有答案都没有真正回答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),特别是在macOS上,其中KVC和KVO用于实现Cocoa绑定。与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依赖关系来轻松实现这一点 - 否则,我们必须编写代码以手动在私有属性中发送通知{{1} 1}}和willSet处理程序。此外,通知KVC系统didSet依赖于dependentProperty的静态属性需要暴露给Objective-C,以便KVC系统找到它并调用它,但它是&#39;与我们代码的客户无关。

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

如您所见,有时可能需要向Objective-C公开方法或属性才能与框架进行交互,而无需向代码的客户端显示。

答案 2 :(得分:22)

@objc / 动态

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

如果您希望Objective-C代码或类访问您的属性/方法,请使用它。

大多数情况下,当你对Swift类的Objective-C基类进行子类化时会发生这种情况。

  

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

这里有关于@objc

的苹果文档

Using Swift from Objective-C

Language Interoperability Compatibility

已更新的链接:看起来这些链接已由apple更新。

答案 3 :(得分:9)

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

@objc public class MyClass

它将类方法公开给Objective C类,所以只有当你的类包含公共函数时才会使用它

答案 4 :(得分:7)

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

在Swift 4中,删除了@objc的一些推理案例。这仅仅意味着在一些其他情况下,在Swift编译器推断出@objc标头之前,它在Swift 4中没有被推断。

阅读有关this change

的Swift演进提案

正如已经提到的,通常@objc是将某些方法暴露给Objective-C运行时,这是Swift与语言互操作的一部分。

答案 5 :(得分:0)

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

要使用Objective-C中的Swift功能:

  1. Swift的课程应从NSObject扩展
  2. 马克·斯威夫特:

    a。 @objcMembers 课程-公开所有 public 字段方法

    b。 @objc 课程-公开public init()
    @objc public 字段方法-有选择地公开它们

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

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

例如:

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