当前位置: 首页 > 面试题库 >

@objc关键字扩展子类行为

武功
2023-03-14
问题内容

有人可以解释为什么@objc在这里需要关键字来编译代码吗?

据我了解,此关键字用于工作ObjC消息方法调度。但这不是一个NSObject实例。

 class MyClass {
 }

 extension MyClass {
     @objc func extensionMethod() { /// THIS LINE
         print("A")
     }
 }

 class SubClass: MyClass {
     override func extensionMethod() {
         print("B")
     }
 }

@objc关键字是否也启用消息分发dynamic?或不?


问题答案:

@objc关键字是否也启用消息分发dynamic

通常不行。通常,@objc属性本身只是将给定的类成员暴露给Objective-C –
Swift仍然可以使用表或静态分派自由地对其进行分派。您需要标记该成员,dynamic就像您希望Swift在调用它时使用消息分发一样。

但是,对于非最终@objc扩展
成员,Swift会自动将其推断为dynamic。为什么?因为出于互操作性的原因,Swift允许@objc扩展成员覆盖和覆盖(就像您可以在子类类别中覆盖Obj-
C方法一样)。为了实现此行为,Swift依赖于Obj-C消息调度。

因此,在扩展中,@objc推断dynamic。您不能覆盖扩展成员而不将其暴露给Obj-
C运行时,因为扩展成员当前无法添加到Swift类vtable(因为Swift vtable当前不能在运行时动态地将成员添加到它们)。

但这不是一个NSObject实例。

在Apple平台上(即具有Obj-C互操作的平台), 所有 Swift类都向Obj-C运行时公开,并且所有隐式继承自名为的特殊Obj-
C基类_SwiftObject,该基类与一致NSObjectProtocol。因此,Swift类无需继承自就能利用消息分发的优势NSObject



 类似资料:
  • 问题内容: 有一个简单的程序代码。在构造函数中,没有扩展到超类的调用,我不明白在这种情况下会发生什么? 问题答案: 没有显式扩展另一个类的每个类都隐式扩展。因此,只需调用Object的no-arg构造函数。 请注意,此显式调用是不必要的,因为编译器会为您添加它。当您要使用参数调用超类构造函数时,只需在构造函数中添加调用。

  • 问题 在子类中,你想要扩展定义在父类中的property的功能。 解决方案 考虑如下的代码,它定义了一个property: class Person: def __init__(self, name): self.name = name # Getter function @property def name(self): retu

  • 问题内容: 所以对于这个项目,我试图在运行时扩展一个类。我想知道,这有可能吗?如果是这样,我该怎么办?是否有用于这些目的的库? 问题答案: CGLib是您要查找的库。它在扩展类或在运行时实现接口方面非常强大,因此许多流行的框架(如Spring或Hibernate)都使用它。 您可以使用以下代码创建类扩展 尽管您可能会使用具有所需逻辑的有用的方法拦截器替换回调。

  • 问题内容: 我有能力在编译时扩展一个类,但是我需要能够在运行时使用已实例化的超类的实例创建此子类的实例。 从理论上讲这应该是可能的,因为已经在子类构造函数之前调用了超类构造函数。 我没有足够的程序访问权限来更改实例化到我的子类或中断原始实例化。 用例:现有一个类X实例的数组。我的代码在之后加载。我需要使用已加载的子类Y扩展X来覆盖实例X之一的方法之一。父程序仅通过该数组访问对象,因此我想用Y实例替

  • 验证码生成 缓存支持

  • 问题内容: 概述:我试图表示数据库中几种类型的实体,它们具有许多共同的基本字段,然后每个实体都具有一些其他字段,这些字段不与其他类型的实体共享。工作流通常会涉及将实体一起列出,因此我决定要有一个带有其公共字段的表,然后每个实体都将具有自己的表及其附加字段。 要实现:所有实体都拥有一个共同的领域“ tatus”;但是,某些实体将仅支持所有可能状态的子集。我还希望每种类型的实体都强制使用其状态子集。最