1

すべてのサブクラスに非常によく似た関数を実装する基本クラスを作成します。これは別の質問で答えられました。しかし、今私が知る必要があるのは、サブクラスオブジェクトを返すために(基本クラスで)さまざまな関数をキャストできるかどうか/方法です。これは、特定の関数だけでなく、その中の関数呼び出しにも当てはまります。

(ちなみに私はCoreDataを使用しています)

基本クラス内の関数として(これは私のサブクラスになるクラスからのものです)

+(Structure *)fetchStructureByID:(NSNumber *)structureID inContext:(NSManagedObjectContext *)managedObjectContext {...}  

そして、与えられた関数内の関数呼び出しとして:

Structure *newStructure = [Structure fetchStructureByID:[currentDictionary objectForKey:@"myId"]];
                                              inContext:managedObjectContext];

構造は私のサブクラスの1つなので、これらの両方を書き直して、「汎用」であり、他のサブクラス(関数を呼び出す人)に適用できるようにする必要があります。

それ、どうやったら出来るの?

更新:第2部では、実際には2つの問題があることに気づきました。[Structurefetch...]を[selffetch...]に変更することはできません。これは、インスタンスメソッドではなく、クラスメソッドであるためです。どうすればそれを回避できますか?

4

1 に答える 1

2

あなたの質問を正しく理解していれば、鍵は[自己クラス]のイディオムだと思います。

更新が現在のクラスのクラスメソッドを呼び出す方法を要求する限り、を使用できます[self class]。のように:

Structure *newStructure = [[self class] fetchStructureByID:[currentDictionary 
                                              objectForKey:@"myId"]];
                                                 inContext:managedObjectContext];

編集:@rpetrichのコメントごとに返すようにこれをやり直しました-はるかにクリーンで、呼び出しているインスタンスのタイプが確実である限りid、その必要性を回避します。-isKindOfClass:-createConfiguredObject

最初の部分については、id(任意のオブジェクトへのポインター)を返すだけで、呼び出されたのと同じクラスのインスタンスを返すことを文書化できます。次に、コードで、メソッド内の新しいオブジェクトをインスタンス化する場所で[selfclass]を使用する必要があります。

たとえば、-createConfiguredObject呼び出されたのと同じクラスのインスタンスを返すメソッドがある場合、次のように実装されます。

// Returns an instance of the same class as the instance it was called on.
// This is true even if the method was declared in a base class.
-(id) createConfiguredObject {
    Structure *newObject = [[[self class] alloc] init];
    // When this method is called on a subclass newObject is actually
    // an instance of that subclass
    // Configure newObject
    return newObject;
}

次に、これを次のようにコードで使用できます。

StructureSubclass *subclass = [[[StructureSubclass alloc] init] autorelease];
subclass.name = @"subclass";

// No need to cast or use isKindOfClass: here because returned object is of type id
// and documented to return instance of the same type.
StructureSubclass *configuredSubclass = [[subclass createConfiguredObject] autorelease];
configuredSubclass.name = @"configuredSubclass";

参考までに、私が参照し-isKindOfClass:て適切なサブクラスにキャストしたのは次のとおりです。

Structure *structure;
// Do stuff
// I believe structure is now pointing to an object of type StructureSubclass
// and I want to call a method only present on StructureSubclass.
if ([structure isKindOfClass:[StrucutreSubclass class]]) {
    // It is indeed of type StructureSubclass (or a subclass of same)
    // so cast the pointer to StructureSubclass *
    StructureSubclass *subclass = (StructureSubclass *)structure;
    // the name property is only available on StructureSubclass.
    subclass.name = @"myname";
} else {
    NSLog(@"structure was not an instance of StructureSubclass when it was expected it would be.");
    // Handle error
}
于 2010-06-08T16:55:14.230 に答える