Can someone explain why isKindOfClass returns different results depending on how the instance was created?
@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
Everything else I can glean from the two types in the debugger is identical. I can even compare both results of NSStringFromClass([instance superclass]) and they are equal.
I must be missing something simple.
Updated Code
This is the unit test code.
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");
Here are the class definitions.
@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
Possible Answer
When I run this logic outside of the test environment its works without issue. Obviously the only difference is removing the STAssertTrue statements and replacing them with my conditions. In this case they both return YES. I even tried to create a simplified example (no ivars in base or derived) and it fails in test but works in standard runtime.
Any ideas why this might only be an issue when testing? Is my test target missing something?
Solved
I had included the .m files in the testing targets compile sources. Once removed this started behaving as expected. Thanks to this post for helping me resolve this.