有人可以解释为什么 isKindOfClass 根据实例的创建方式返回不同的结果吗?
@interface BaseClass
...
@interface DerivedClassA : BaseClass
...
DerivedClassA *instance = [[DerivedClassA alloc] init];
[instance isKindOfClass:[BaseClass class]]; // yields YES
Class c = NSClassFromString(@"DerivedClassA");
id instance = [[c alloc] init];
[instance isKindOfClass:[BaseClass class]]; // yields NO
我可以从调试器中的两种类型中收集到的所有其他内容都是相同的。我什至可以比较 NSStringFromClass([instance superclass]) 的两个结果,它们是相等的。
我一定错过了一些简单的东西。
更新代码
这是单元测试代码。
LightingUnit *u1 = [[LightingUnit alloc] init];
STAssertTrue([u1 isKindOfClass:[ModelBase class]], @"should be derived from base");
Class uc = NSClassFromString(@"LightingUnit");
id u2 = [[uc alloc] init];
STAssertTrue([u2 isKindOfClass:[ModelBase class]], @"should be derived from base");
这是类定义。
@interface ModelBase : NSObject
@property (readonly) NSString *__type;
- (id)initWithDictionary:(NSDictionary *)dictionary;
- (NSMutableDictionary *)dictionary;
@end
@interface LightingUnit : ModelBase
@property (strong, nonatomic) NSString *name;
@property NSInteger unitId;
@end
可能的答案
当我在测试环境之外运行这个逻辑时,它的工作没有问题。显然,唯一的区别是删除 STAssertTrue 语句并用我的条件替换它们。在这种情况下,它们都返回 YES。我什至尝试创建一个简化的示例(基础或派生中没有 ivars),它在测试中失败,但在标准运行时工作。
任何想法为什么这可能只是测试时的一个问题?我的测试目标是否遗漏了什么?
解决了
我已将 .m 文件包含在测试目标编译源中。删除后,它开始按预期运行。感谢这篇文章帮助我解决了这个问题。