ファクトリメソッドを持つフレームワーククラスから継承したいと思います。ファクトリメソッドが継承したクラス型のオブジェクトを返すようにするにはどうすればよいですか?私は同じような状況を記述するthis useful articleを見つけましたが、その場合はスーパークラスを制御できます。たとえば、のサブクラスで、imageNamed:
が私のサブクラス型のオブジェクトを返すと書いてもいいですか?ご例えば目的ファクトリメソッドを持つCクラスの継承
答えて
私はファクトリメソッドを持つフレームワーククラスから継承したいと思います。ファクトリメソッドが継承したクラス型のオブジェクトを返すようにするにはどうすればよいですか?
これはあなたがしなければならない必要があるすべてである:
その後@interface MONImage : UIImage
@end
@implementation MONImage
@end
:
私がいることを、たとえば、UIImageのサブクラスを書くことができますどのようにMONImage * image = [MONImage imageNamed:name];
imageNamed:私のサブクラス型のオブジェクトを返しますか?
+[UIImage imageNamed:]
の実装はこのアプローチからサブクラスを書きました。したがって、このメソッドを自分で実装する必要があります。
+ (instancetype)imageNamed:(NSString *)pName;
とどのように1 はそれを実装する必要があります: - +[UIImage imageNamed:]
は書い
+ (instancetype)imageNamed:(NSString *)pName
{
MONImage * image = [[self alloc] initWithThisDesignatedInitializer:pName];
^^^^ NOTE: self, not a concrete class
...set up image...
return image;
}
をしかし、彼らはそのようにしませんでした。ここ
は1 がファクトリメソッドを宣言する必要があります方法ですサブクラスを返し、MONImage * img = [MONImage imageNamed:pName];
と書くとUIImage
を返します。時にはそれは良い理由のために行われます。いくつかのメソッドは「最終的な」セマンティクスを持つ必要があります。これは、クラスクラスターのように、メソッドが複数の型を返すことがある場合によく表示されます。言語は「最終的な」方法を表現しませんが、そのような方法は少なくとも文書化されるべきです。
@interface MONImage : UIImage
+ (instancetype)imageNamed:(NSString *)pName;
@end
@implementation MONImage
+ (instancetype)imageNamed:(NSString *)pName
{
UIImage * source = [UIImage imageNamed:pName];
CGImageRef cgImage = source.CGImage;
if (cgImage)
return [[self alloc] initWithCGImage:cgImage];
// try it another way
return nil;
}
@end
注UIImage
sおよびCGImage
sが不変であること:これUIImage
場合に周りに来て
。これにより、画像データのディープコピーが作成されるべきではありません。
+1はinstancetypeを使用しています。 – Abizern
これは '[UIImage imageNamed:]'のキャッシングビヘイビアも提供しますか?もしそうでなければ、元のイメージへの参照を 'MONImage'に保存するべきでしょう。しかし、本当に素晴らしい解決策。 –
@JonathanCichon '+ imageNamed:'の検索動作を保持します。イメージをロードしてからキャッシュします。キャッシングの実装の正確な振る舞いは抽象化されているので、私の結論は、この点で同一であることが保証されていないということです。私はキャッシングに関して同じであると仮定しますが、私はそれを証明していません。良い質問。 – justin
:
- サブクラス
UIImage
MyImage
、たとえば、にあなたが行われる必要があることを具体的な何かをするimageNamed:
メソッドを実装します。- コールそのクラスにそのメソッド:私の問題を解決し
MyImage *newImage = [MyImage imageNamed:imageName];
これは実際には役に立ちません。あなた自身の 'imageNamed'の実装で' super'を呼び出すことができないので、これは 'UIImage'型のインスタンスを返すことになります。 –
彼はスーパーに電話する必要があると誰が言いますか?メソッド内でサブクラスのオブジェクトを割り当てて初期化し、それを返すことができます。そして皆さんが知っているように、このコンベンションでは、サブクラスがスーパークラスの指定された初期化子を呼び出すことがあります。この初期化子は、 'id'型のオブジェクトを返します。とにかく、これは、OPが求めていたことに基づいて作られた実例です。詳細はユーザーに任せられますが、便利なコンストラクターの原則は、自分自身のクラスのオブジェクトをallocしてinit'ingすることは健全です。 – Abizern
はい、この場合、「マジック」リンゴは 'imageNamed:'にありますが、これは非常に便利で、私は自分でこれを実装したいと思っていません。しかし、あなたは正しいです、あなたの答えは「間違っていません」しかし、私はこのケースではあまり役に立たないと思います。 –
アプローチは、(クレジットは私の質問のコメントでジョナサンCichonに行く)相続の代わりにカテゴリを使用することでした。私はAssociative Referencesを使用して、ここで多く議論されているように、カテゴリの実装に追加データを宣言して格納します。 Jonathanによって提案されたNSObject
category implementationに注目して、本当に簡単でエレガントにして、どのオブジェクトにも関連参照を追加するようにしたいと思います。
私はあなたの問題を解決してうれしいですが、あなたの質問は便利なコンストラクタをオーバーライドすることでした。次に、クラス拡張の外のクラスにストレージを追加する質問に変更しました。実際には2つの質問と回答が同時に行われます。 – Abizern
元のフレームワーククラスを追加のデータで拡張し、元の便利なコンストラクタを使用できるようにする必要がありました。私が元の質問をしたとき、私はこれをどうやって行うのか分からず、継承で達成できると考えました。あなたは、私がクラスに追加のデータを追加する必要があることを正確には指定せず、 "継承"を書いたという観点からは正しいです。一方、継承を使用しない場合でも、ジョナサンのソリューションは私の問題を完全に解決します。 – MrTJ
注:私は元の質問を変更せず、この答えのassoc.refsのヒントを将来の読者の参考としてのみ追加しました。 – MrTJ
- 1. 目的C継承
- 2. 目的のCの継承
- 3. 3つの派生クラスを持つC++の多重継承
- 4. C++クラス継承
- 5. クラス継承を持つHibernateのSubselect
- 6. Boost ::継承を持つクラスのPythonバインディング
- 7. 継承 - ターゲット固有の継承クラスC#
- 8. C#の継承/クラス
- 9. C++クラスの継承
- 10. 抽象クラス継承を持つJPAエンティティ
- 11. C#CodeProvider:クラス継承?
- 12. C++で継承されたクラスを持つリンクリスト?
- 13. 継承を持つ静的ブロック
- 14. Spring XML設定でのファクトリメソッドBean継承
- 15. 継承リストを持つC++テンプレート宣言
- 16. MultiLevel継承、クラスCはクラスAを継承できますか?
- 17. C++クラスの継承とテンプレート
- 18. C#インターフェイスとクラスの継承
- 19. 継承したクラスの戻り値の型を持つ継承されたメソッド
- 20. 静的クラスと継承
- 21. PHP動的クラス継承
- 22. クラス継承とテンプレートクラスC++
- 23. 仮想クラスや継承C++
- 24. C#ジェネリック継承基本クラス
- 25. クラス継承とインターフェイス継承
- 26. 継承メモリストレージを持つオブジェクト
- 27. 継承エラーを持つジェネリック
- 28. 選択的継承C++
- 29. C++継承と動的ライブラリ
- 30. C#:推移的継承
UIImageにカテゴリを書くことで、あなたが望むものを達成できますか? –
はい、私は今この方向について考えています。私はいくつかの追加のクラスメンバー(プロパティ)が必要なだけで、objc_setAssociatedObjectとお友達との混乱を避けたいと思っていました。まったく別の問題のために、このタイプの回避策を作成するのがエレガントではないからです。しかし、私は選択肢がないことをますます心配しています。 – MrTJ
この[NSObject](https://github.com/pixelflut/PixLib-OpenSource/blob/master/PixLib%20OpenSource/NSObject%2BPixLib.m)カテゴリを見てください。 'setRuntimeProperty:name:'と 'runtimeProperty:'の2つのメソッドは、関連オブジェクトの設定とアクセスを容易にします。 –