私は次のオブジェクトの構造を持っています:
動物、犬、猫。ご想像のとおり、犬と猫は動物から受け継がれています。
そして私は農場のクラスを持っています:
@implementation AnimalFarm
-(Animal*) createAnimal:(AnimalType)type{
switch (type) {
case CAT:
return [Cat new];
case DOG:
return [Dog new];
default:
return [Animal new];
}
}
@end
そして私はユニットテストを試みました:
AnimalFarm *farm = [AnimalFarm new];
Animal *dog = [farm createAnimal:DOG];
Animal *cat = [farm createAnimal:CAT];
STAssertTrue([cat isMemberOfClass:[Cat class]],@"cat is not a cat!");
STAssertTrue([dog isMemberOfClass:[Dog class]],@"Dog is not a dog!");
STAssertTrue([cat isKindOfClass:[Animal class]],@"Cat is not an animal!");
STAssertTrue([dog isKindOfClass:[Animal class]],@"Cat is not an animal!");
クラスの実装:
@interface Cat : Animal {
}
@end
@implementation Cat
-(NSString*) say{
return @"miau";
}
@end
犬の実装も同様です。
しかし、isKindOfClassもisMemberOfClassも期待どおりに機能しませんでした。
私は何かが足りないのですか?
スイッチの代わりにIFを使用すると、すべてがうまくいきます...しかし、違いは何ですか?
動作するcreateAnimalの実装:
-(Animal *) createAnimal:(AnimalType)type {
if (type == DOG) {
return [Dog new];
} else if (type == CAT) {
return [Cat new];
} else {
return [Animal new];
}
isMemberOfClass:
は、インスタンスのクラスがまったく同じである場合にのみYES
を返しますが、インスタンスのクラスが同じである場合、またはisKindOfClass:
はYES
を返します。与えられたクラス。
たとえば、これはNo!
を出力します。
BOOL result = [[NSMutableArray array] isMemberOfClass:[NSArray class]];
NSLog (@"%@", result? @"Yes!" : @"No!");
しかし、これはYes!
を出力します:
BOOL result = [[NSMutableArray array] isKindOfClass:[NSArray class]];
NSLog (@"%@", result? @"Yes!" : @"No!");
これは、NSMutableArrayがNSArrayの種類であるが、NSArrayクラスのメンバーではないためです(そうでない場合、NSMutableArrayではありません) 。
FoundationとCocoa全体に、多数の「クラスクラスター」があります。これについて詳しくは、 Appleの開発者Webサイト のドキュメントを参照してください。クラスクラスターの性質上、おそらくNSString
オブジェクトを作成すると、isMemberOfClass:[NSString class]
テストに失敗する可能性があります。
isKindOfClass:
もisMemberOfClass:
も正しい値を返さない場合は、実際のオブジェクトがどのクラスにあるかを確認してください
NSLog(@"cat class = %@, dog class = %@", [cat className], [dog className]);
これらが想定以外のものを返している場合は、ファームクラスに問題があります。
あなたの問題は他の場所にあります。
Animal
、Dog
、およびCat
クラスを作成しましたが、上記の4つのケースに合格しました。参考までに、私のコードは次のとおりです。 http://pastie.org/774468
出力:
2010-01-11 19:45:10.259 EmptyFoundation[83698:a0f] [cat isMemberOfClass:[Cat class]] PASSED
2010-01-11 19:45:10.265 EmptyFoundation[83698:a0f] [dog isMemberOfClass:[Dog class]] PASSED
2010-01-11 19:45:10.265 EmptyFoundation[83698:a0f] [cat isKindOfClass:[Animal class]] PASSED
2010-01-11 19:45:10.273 EmptyFoundation[83698:a0f] [dog isKindOfClass:[Animal class]] PASSED
編集:
AnimalFarm
オブジェクトがエラーの原因である可能性がわずかにあったと思いますが、その方法で動物オブジェクトを作成しようとすると、同じ結果が得られました(コード: http:// pastie .org/77448 ):
2010-01-11 19:51:35.144 EmptyFoundation[83741:a0f] [cat isMemberOfClass:[Cat class]] PASSED
2010-01-11 19:51:35.156 EmptyFoundation[83741:a0f] [dog isMemberOfClass:[Dog class]] PASSED
2010-01-11 19:51:35.157 EmptyFoundation[83741:a0f] ![ant isMemberOfClass:[Cat class]] PASSED
2010-01-11 19:51:35.157 EmptyFoundation[83741:a0f] [cat isKindOfClass:[Animal class]] PASSED
2010-01-11 19:51:35.157 EmptyFoundation[83741:a0f] [dog isKindOfClass:[Animal class]] PASSED
2010-01-11 19:51:35.158 EmptyFoundation[83741:a0f] [ant isKindOfClass:[Animal class]] PASSED
編集#2:
If ... else ifステートメントは機能するがswitchステートメントは機能しないという観察に基づいて、上記で投稿したコードをswitchステートメントを使用するように変更しました....それは問題なく機能しました。したがって、私のコメント/質問は次のようになります。if/ switchステートメントでは、これらの定数DOG
およびCAT
を使用しています。それらはどこで定義されていますか?