Objective c isKindOfClass 误解?

发布于 2024-08-18 01:09:34 字数 1326 浏览 2 评论 0原文

我有以下对象结构:

动物、狗和猫。正如您所期望的,Dog 和 Cat 是从 Animal 继承的。

我有一个农场类:

 @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 而不是 switch 时,一切都会顺利......但是有什么区别呢?

createAnimal 的实现有效:

-(Animal *) createAnimal:(AnimalType)type {

  if (type == DOG) {
    return [Dog new]; 
  } else if (type == CAT) {
    return [Cat new]; 
  } else {
    return [Animal new];
  }

I have following structure of objects:

Animal, Dog and Cat. As You expect Dog and Cat are inherited from Animal.

And I've a farm class:

 @implementation AnimalFarm

-(Animal*) createAnimal:(AnimalType)type{

  switch (type) {

    case CAT:
      return [Cat new];

    case DOG:
      return [Dog new];

    default:
      return [Animal new];
  }

}

@end

and I tried to unit test:

  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!");

Implementation of classes:

@interface Cat : Animal {

}


@end

@implementation Cat

  -(NSString*) say{
    return @"miau";
}

@end

Implementation of dog is similar.

but neither isKindOfClass or isMemberOfClass worked as I expected....

Am I missing something?


When I use IFs instead of switch then everything goes well ... but what is the difference?

Implementation of createAnimal which works:

-(Animal *) createAnimal:(AnimalType)type {

  if (type == DOG) {
    return [Dog new]; 
  } else if (type == CAT) {
    return [Cat new]; 
  } else {
    return [Animal new];
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

予囚 2024-08-25 01:09:34

如果实例的类完全相同,则 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 开发者网站。由于类簇的性质,如果您创建一个 NSString 对象,它可能会失败 isMemberOfClass:[NSString class] 测试。

如果 isKindOfClass:isMemberOfClass: 都没有返回正确的值,请查看实际对象属于哪个类。

NSLog(@"cat class = %@, dog class = %@", [cat className], [dog className]);

如果这些返回的内容与预期的内容不同,则有是你的农场类别的问题。

isMemberOfClass: will only return YES if the instance's class is exactly the same, however isKindOfClass: will return YES if the instance's class is the same, or a subclass of the given class.

For example this will output No!:

BOOL result = [[NSMutableArray array] isMemberOfClass:[NSArray class]];
NSLog (@"%@", result? @"Yes!" : @"No!");

But this will output Yes!:

BOOL result = [[NSMutableArray array] isKindOfClass:[NSArray class]];
NSLog (@"%@", result? @"Yes!" : @"No!");

This is because an NSMutableArray is a kind of NSArray, but it isn't a member of the NSArray class (otherwise it wouldn't be an NSMutableArray).

Throughout Foundation and Cocoa, there are a number of "class clusters". You can read more about this in the documentation on Apple's developer web site. Due to the nature of class clusters, if you create perhaps an NSString object, it may fail the isMemberOfClass:[NSString class] test.

If neither isKindOfClass: or isMemberOfClass: is returning the correct value, see what class the actual object is with

NSLog(@"cat class = %@, dog class = %@", [cat className], [dog className]);

If these are returning anything other than what they are supposed to, then there is a problem with your farm class.

白况 2024-08-25 01:09:34

你的问题出在别处。

我创建了您的 AnimalDogCat 类,以及您上面通过的四种情况。作为参考,这是我的代码: 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/774480):

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 语句中,您使用这些常量 DOGCAT。这些是在哪里定义的?

Your problem lies elsewhere.

I created your Animal, Dog, and Cat classes, and the four cases you have above passed. For reference, here is my code: http://pastie.org/774468

It outputs:

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

EDIT:

I suppose there was a slight possibility that your AnimalFarm object was the source of the error, but I just tried creating the animal objects that way and got the same results (code: http://pastie.org/774480):

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

EDIT #2:

Based on your observation that an if...else if statement works but the switch statement does not, I modified the code I posted above to use a switch statement.... and it worked just fine. So my comment/question stands: In your if/switch statements, you're using these constants DOG and CAT. Where are those defined?

泪之魂 2024-08-25 01:09:34

您错过了休息时间,这就是您的开关无法工作的原因。它应该看起来像这样。

switch (type) {

 case CAT:
   return [Cat new];
 break;
 case DOG:
   return [Dog new];
 break;
 default:
   return [Animal new];
 break;
}

You are missing breaks, that's why your switch isn't working. It should look like this.

switch (type) {

 case CAT:
   return [Cat new];
 break;
 case DOG:
   return [Dog new];
 break;
 default:
   return [Animal new];
 break;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文