2017-08-26 1 views
3

私のアプリでは、タイプEKEventのカレンダーイベントを読んでいました。計算されたvarsがたくさんあるエクステンションを作ったので、カレンダーの各イベントの長さ、工数などを簡単に取得できます。しかし、大規模ではパフォーマンスが悪いので、代わりにすべての余分なデータをキャッシュするために、レイジー・ヴァルを使用したいと考えています。スーパークラスのインスタンスでサブクラスを初期化するにはどうすればいいですか?

私はEKEventのサブクラスを作成したいと思っています。カスタムイベントは、怠惰なvarsを追加しますが、私の問題は、EKEventStoreが常にEKEventsを返すため、私はCustomEventサブクラスのインスタンスに順番に変換する必要があります。怠惰なバールなどにアクセスできるようにすること。

単純な型キャストでは不十分で、私は遊び場で何がうまくいくか見るために試しましたが、役に立たないものはありません。 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) 

答えて

0

をマッピングする必要があると思いますので、それは、私の好きな解決策ではないでしょうObjective-Cの土地での作業は、ネイティブクラスをラップし、自動的にメッセージ(追加を除く)すべてを転送するオプションがあります:

- (NSMethodSignature*) methodSignatureForSelector: (SEL) selector 
{ 
    NSMethodSignature *ours = [super methodSignatureForSelector:selector]; 
    return ours ?: [wrappedObject methodSignatureForSelector:selector]; 
} 

これはへの転送のために必要だったすべてがある場合、私は覚えていないことしかし、それはかなり近いはずです。また、また、

秒を私はこれがスウィフトと遊ぶだろうかわからないので、私たちはObjective-Cの日からこのトリビアの興味深い作品を検討し、よりよい解決策を探しことができると思います...


少し厄介なオプションは、 associated objects featureを使用して、キャッシュされたデータを元のインスタンスにリンクすることです。そうすれば、あなたはあなたのエクステンションにアプローチすることができます。

3

子クラスインスタンスを作成するときに、基本クラスオブジェクトの既存のインスタンスを使用する方法はありません(ほとんどのオブジェクト指向言語では)。

  1. 使用組成物:NativeRectangleが含まれているCustomRectangleを作成し、あなたが必要とするそれまでのすべてのメソッドを転送する一般的なプログラミングのスタンドポイントから

    あなたはこのような状況では2つのオプションがあります。

  2. NativeRectanglesを追加情報にリンクするマップを使用します。 Objective CとSwiftでは、objc_AssociationPolicyを使用して、そのような内部マップを最も簡単に作成できます。 https://stackoverflow.com/a/43056053/278842

Btwを参照してください。 width * heightという単純な計算を「キャッシング」することでスピードアップする方法はありません。

+0

私がこのようなことをしなければならないときには、通常、構図は私の心に来る最初の考えです。 – Abizern

+0

ありがとうございます - 私はラッパークラスを作成し、プロパティをマップする必要があります、私は推測する...私はより洗練されたソリューションを望んでいた。 width * heightのシンプルな "キャッシング"は例のためのものでした... –

0

独自のCustomRectangle(object: rect)を作成したため、swiftはデフォルトのinit()を提供しません。明示的にあなた自身の財産を保有し、super.init()に電話する必要があります。クラスもスーパークラスから継承されています。 -

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

    // Super class custom init() 
    init(width: Int, height: Int) { 
     self.width = width 
     self.height = height 
     super.init() 
    } 
} 

class CustomRectangle: NativeRectangle { 

    // computed property area 
    var area: Int { return width * height} 

    // Sub class Custom Init 
    init(object:NativeRectangle) { 
     // call to super to check proper initialization 
     super.init(width: object.width, height: object.height) 
    } 
} 

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

let customRect = CustomRectangle(object: rect) 

print(customRect.area) //2000 
+0

私はそれがEKEventsの解決策ではないと考えています。しかし、他のタイプの場合は役に立つかもしれません。 @Christopher Oezbek –

+0

@Esben von Buchwaldの勧告は、EKEventsや初期化の仕組みについてはあまり気にしていませんが、上記の答えは基本的な初期化プロセスです。実際、あなたはOezbekの解決策に固執することができます。 –

関連する問題