2

私は、さまざまなクラスによってさまざまな深さでサブクラス化される Objective-C クラスのコレクションを持っています。オブジェクト全体が初期化されたら (すべてのサブクラスの init 関数が終了したら)、必要に応じてサブクラスによってオーバーライドされる "Update Cache" メソッドを実行する必要があります。

私の問題: クラス ツリーにさまざまな継承の深さがあるため、[self UpdateCache] を配置できる場所が 1 つもなく、初期化されていないサブクラスがないことを確認できます。唯一可能な解決策は、各クラスの初期化後に [super init] を呼び出して、親クラスが常に最後に呼び出されるようにすることです。これは、Objective-C を記述するすべてのガイドラインに反するため、避けたいと考えています。この問題に対する明確な解決策はありますか?

以下にコード例を示します。

@interface ClassA : NSObject

-(void)UpdateCache
@end

@interface ClassB : ClassA

-(void)UpdateCache
@end

@interface ClassC : ClassB

-(void)UpdateCache
@end

実装のために、どのクラスが初期化されたかに関係なく、すべてのサブクラスが初期化されたことを確認した後で、どうにかして UpdateCahce を呼び出す必要があります。

@implementation A
-(id)init
{
   if(self = [super init])
   {
       // Placing [self UpdateCache] here would make it be called prior to 
       // B and C's complete init function from being called.
   }
}

-(void)UpdateCache
{

}


@end

@implementation B
-(id)init
{
   if(self = [super init])
   {
       // Placing [self UpdateCache] would result in UpdateChache not being
       // called if you initialized an instance of Class A
   }
}

-(void)UpdateCache
{
   [super UpdateCache];
}

@end

@implementation C
-(id)init
{
   if(self = [super init])
   {
       // Placing [self UpdateCache] would result in UpdateChache not 
       //being called if you initialized an instance of Class A or B
   }
}

-(void)UpdateCache
{
   [super UpdateCache];
}

@end
4

4 に答える 4

3

初期化の直後にキャッシュを更新するのではなく、最初に使用する直前に更新してみませんか? おそらく、init でcacheIsDirty設定したブール値のインスタンス変数を持つことができます。次に、キャッシュがダーティな場合、キャッシュTRUEのゲッターが最初に呼び出されます。updateCache常に getter を使用し、インスタンス変数を直接使用しないと仮定すると (Objective-C ではこれが適切な方法です)、クライアントは違いに気付かないはずです。

于 2012-06-13T18:17:51.020 に答える
1

サブクラスには固有の init メソッド シグネチャが必要ですか? (たとえば、オブジェクトの初期化に必要なサブクラス固有のパラメーター) そうでない場合は、単純なファクトリのような設計パターンに従っても問題なく動作する可能性があります。

親/基本クラスを追加する例:

+(id)buildSelf {
    YourParentClass* obj = [[[self alloc] init] autorelease];
    if (obj) {
        [obj updateCache];
    }
    return obj;
}

必要に応じて、すべてのサブクラスが使用するパラメータを追加します。

繰り返しますが、サブクラスが独自の init メソッド シグネチャをサポートする必要がある場合、これはうまく機能しません。

于 2012-06-13T18:44:50.763 に答える
0

仮想メソッドを宣言し、必要なときに呼び出します。

これはObjectiveCなので、Objective-Cで純粋仮想メソッドを実装するを参照してください。

于 2012-06-13T17:46:02.260 に答える
0

はい、しばらく前に同様の質問をしました...オブジェクトのインスタンスに「フック」/「プロキシ」を追加して、-forwardInvocation:セレクターをオーバーライドし、必要なことを実行できます。元の質問はここにあり、それに対する私の答えは受け入れられたものです。

于 2012-06-13T17:51:44.793 に答える