If I have a class hierarchy in which subclasses require use of more specific types than those specified in the superclasses' ivars, is it better to declare the superclass ivar as id, or to type it and then cast where necessary in the subclasses?
For example I have a superclass which uses an ivar of type Thing:
@interface SuperClass {
Thing *_typedIvar; // OR
id anonIvar;
}
@property (nonatomic, retain, readwrite) Thing *_typedIvar;
@property (nonatomic, retain, readwrite) id anonIvar; // OR
Then in a subclass implementation I want to use a SubThing to get at its methodNotInThing
@interface SubClass : SuperClass {
}
@implementation {
- (void)aMethod {
SubThing *subtypedIvar = (SubThing *)self.typedIvar;
[subtypedIvar methodNotInThing];
// OR
[self.anonIvar methodNotInThing];
}
}
(I'm assuming here that the subclass has appropriately assigned a SubThing to the ivar).
I've used both approaches (in my thus far short time using ObjC), and am never quite resolved regarding which is best. I like the compiler checking offered by use of real types, along with being able to use dot syntax where appropriate. But the constant casting in subclasses gets pretty ugly, requires more code, and somehow tastes worse to me (which is hardly an argument, I suppose). However I like the fact in the typed version that the superclass in effect documents what subclasses should do with the ivar.
Which of the above would be the better approach, and why?
I would argue that using real types is better, despite the drawback of having your code littered with casts.