isKindOfClass行为
有人可以解释为什么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([实例超类])的结果和它们相等。
我必须错过简单的东西。
更新的代码
这是单元测试代码。
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文件包含在测试目标编译源中。 一旦删除,开始按预期行事。 感谢这篇文章帮助我解决这个问题。
我在您的测试应用程序中添加了您的代码。 我不得不改变两个instance
变量的名称,之后编译器给了我一个警告(“Class method'+ alloc'not found”),当我运行它时,程序崩溃了。
然后我改变了这一行:
@interface BaseClass : NSObject
即我从NSObject
派生的BaseClass
。 没有更多的编译器警告并且代码按预期运行,即第二个是isKindOfClass
返回YES。
我不知道是否缺少NSObject
是什么原因导致你的问题。 如果不是,那么其他人必须介入。如果是,我想知道你是如何运行你的代码的。
BaseClass
是否从NSObject
继承将改变这个代码的结果。 以下是两种可能性:
@interface BaseClass
如果你已经定义了BaseClass
而没有从NSObject
继承,那么坦白地说,我很惊讶编译器让你摆脱了设置你的instance
变量的风险。 除非你在BaseClass
上定义了自己的+alloc
和-init
方法(这是可能的),那么你的测试的第一行根本不起作用。 如果您确实定义了适当的+alloc
和-init
方法,那么您仍然会遇到-isKindOfClass:
因为您还需要自己定义它。 所以基本上这不起作用,让我们看看下一个选项...
@interface BaseClass : NSObject
测试的第一行(创建instance
)应该可以正常工作。
[instance isKindOfClass:[BaseClass class]]
返回适当的值YES
。
你的class c
初始化应该能够正常工作。
我怀疑这里省略了一些东西,因为最后一行应该返回YES
,并且发布的代码(假设BaseClass
继承自NSObject
)......最后一行应该返回YES
。 我怀疑可能发生了什么是instance
有不知何故通过不正确的初始化/打字错误/等,包含nil
。 在这种情况下,发送消息只会返回nil
,因此发送-isKindOfClass
将产生NO
。