有人可以解释为什么 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),它在测试中失败,但在标准运行时有效。
有什么想法为什么这可能只是测试时的问题吗?我的测试目标是否缺少某些内容?
Solved
我已将 .m 文件包含在测试目标编译源中。一旦删除,它就开始按预期运行。谢谢这个帖子 https://stackoverflow.com/questions/5364074/iskindofclass-and-nsstringfromclass-disagree-about-uiapplicationdelegate帮助我解决这个问题。