如何使用其超类的实例初始化我的子类?

Esb*_*ald 5 casting subclassing ios eventkit swift

在我的应用程序中,我阅读了EKEvent类型的日历事件,并且我已经使用大量计算变量进行了扩展,因此我可以轻松获得日历中每个事件的持续时间,工时等数量.但是在大规模中,性能很差 - 所以我想使用lazy vars来缓存我所有的额外数据.

因此,我想创建一个EKEvent的子类 - 名为CustomEvent,它添加了懒惰的变量,但我的问题是EKEventStore总是返回EKEvents,我需要将它转换为我的CustomEvent子类的实例,以便能够访问懒惰的vars等

一个简单的类型转换是不够的,我已经在操场上试过,看看哪些可行,但没有任何用处.我需要一个CustomRectangle的特殊构造函数,它可以从NativeRectangle初始化一个CustomRectangle.另一种解决方案是创建一个包装类,将原始对象保存为属性,但这不是我最喜欢的解决方案,因为我必须映射所有方法和属性

class NativeRectangle: NSObject {
    var width: Int
    var height: Int

    init(width: Int, height: Int) {
        self.width = width
        self.height = height
        super.init()
    }
}

class CustomRectangle: NativeRectangle {
    var area: Int { return width * height}
}

let rect = NativeRectangle(width: 100, height: 20)

let customRect = CustomRectangle(rect) // This fails, i need a constructor

print(customRect.area)
Run Code Online (Sandbox Code Playgroud)

Chr*_*bek 5

在 Swift 中(通常在大多数面向对象语言中)无法在创建子类实例时使用基类对象的现有实例。

从一般编程的角度来看,在这种情况下您有两种选择:

  1. 使用组合:使 CustomRectangle 包含一个 NativeRectangle 并将您需要的所有方法转发给它。

  2. 使用地图将 NativeRectangles 链接到其他信息。在 Objective C 和 Swift 中,您可以使用 objc_AssociationPolicy 最轻松地拥有这样的内部映射。见/sf/answers/3013923741/

顺便提一句。将一个简单的计算“缓存”为width * height.


zou*_*oul 0

如果您已经在 Objective-C 领域工作,那么\xe2\x80\x99s 可以选择包装本机类并自动转发所有(除了添加的)消息:

\n\n
- (NSMethodSignature*) methodSignatureForSelector: (SEL) selector\n{\n    NSMethodSignature *ours = [super methodSignatureForSelector:selector];\n    return ours ?: [wrappedObject methodSignatureForSelector:selector];\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我不记得\xe2\x80\x99 是否这是转发工作所需的一切,但它应该非常接近。另外,我不知道 \xe2\x80\x99 不知道这将如何与 Swift 一起使用,所以我想我们可以认为这是 Objective-C 时代的一个有趣的琐事,并寻找更好的解决方案\xe2\x80\xa6

\n\n
\n\n

我想到的第二个也有点老套的选项是使用关联对象功能将缓存的数据链接到原始实例。这样你就可以保持你的扩展方法。

\n