Если у меня есть иерархия классов, в которой подклассы требуют использования более специфических типов, чем те, которые указаны в иварах суперклассов, лучше объявить суперкласс ивар как id или ввести его, а затем при необходимости привести его к подклассам
Например, у меня есть суперкласс, который использует ивар типа Thing:
@interface SuperClass {
Thing *_typedIvar; // OR
id anonIvar;
}
@property (nonatomic, retain, readwrite) Thing *_typedIvar;
@property (nonatomic, retain, readwrite) id anonIvar; // OR
Затем в реализации подкласса я хочу использовать SubThing, чтобы получить его методNotInThing
@interface SubClass : SuperClass {
}
@implementation {
- (void)aMethod {
SubThing *subtypedIvar = (SubThing *)self.typedIvar;
[subtypedIvar methodNotInThing];
// OR
[self.anonIvar methodNotInThing];
}
}
(здесь я предполагаю, что подкласс соответствующим образом назначил SubThing для ивара).
Я использовал оба подхода (за короткое время, пока я использовал ObjC), и я никогда не решался относительно того, какой из них лучше. Мне нравится проверка компилятора, предлагаемая с использованием реальных типов, а также возможность использовать точечный синтаксис, где это уместно. Но постоянное приведение в подклассы становится довольно уродливым, требует больше кода, и почему-то мне на вкус хуже (что вряд ли является аргументом, я полагаю). Однако мне нравится тот факт, что в типизированной версии суперкласс фактически документирует, что подклассы должны делать с ivar.
Какой из вышеперечисленных будет лучшим подходом и почему?