不能子类 DispatchGroup - “只能通过 Objective-C 运行时可见”?

Fat*_*tie 1 objective-c-runtime swift swift3

子类是不可能的DispatchGroup,怎么做?

笔记:

这终于在 iOS 10+ 中得到修复

例如,携带一个带状态的包,

class PushDispatchGroup: DispatchGroup {
    var sentIds: [(tableName: String, rowId: String)] = []
}
Run Code Online (Sandbox Code Playgroud)

感谢shallowThought 指出这是在iOS10 中修复的。

Rob*_*ier 5

如何从“仅通过 Objective-C 运行时可见”的类继承?

你没有。

这并没有像您思考的那样围绕一个适当的“对象”。它包裹在 a 周围dispatch_group,这是一个 C 结构体。这个类不是为子类化而设计的,也不会以正常方式桥接到 ObjC,所以你也不能在那里子类化它。

直接桥接到低级 C 类型的“对象”通常具有非常不寻常的结构,系统的某些部分是硬编码的以知道如何处理(这种情况一直发生在像NSString和 之类的免费桥接中CFString)。在许多情况下,通过仔细选择结构,这些类型被设计为在内存布局上是相同的(我没有分开DispatchGroup,但它看起来像这个组中的一个)。如果是这样,您就不能添加任何存储,因为这样内存布局就会不同并且您会破坏桥接。

正如各种评论者所说,你也不应该这样做,这就是为什么没有简单的答案来说明如何做到这一点。没有明确设计用于子类化的类在 Swift 中很难或不可能进行子类化(这经常出现在比 更难的类型周围DispatchGroup,答案是一样的:这是故意的;不要这样做)。

  • “Open”刚刚在 Swift 3 中添加。他们没有审核每个 Cocoa 类来决定哪个应该打开,因此“open”是 Cocoa 导入器的默认值。如果它是为子类化而设计的,那么文档中几乎总是会有“子类化注释”来解释如何进行子类化。一个类可以任意子类化的情况非常罕见(这是子类化的一个主要问题,也是避免子类化的一个原因:子类化几乎总是需要接口中没有的特殊知识)。 (2认同)