我有3个Objective-C类:
Animal - a subclass of NSObject
Feline - a subclass of Animal
Cat - subclass of Feline
这三个类中的每一个都实现(我认为是)它自己的私有方法(-private_Setup),用于设置:
e.g。在动物:
-(instancetype)init
{
self = [super init];
if (self) {
[self private_Setup];
}
return self;
}
在猫类和猫类中也是如此。
运行时提供了所需类的列表,因此我根据类名列表创建各种类的实例。
e.g。
NSString *className = ... // @"Animal", @"Feline" or @"Cat".
id animal = [[NSClassFromString(className) alloc] init];
问题:
如果我创建了Cat的实例,则会为继承链中的每个步骤多次调用-private_Setup。例如,Cat的调用链:
-[Cat init]
-[Feline init]
-[Animal init]
-[Cat private_Setup] // First!
然后,来自:
-[Feline init]
-[Cat private_Setup] // Second!
然后,来自:
-[Cat init]
-[Cat private_Setup] // Third!
因此,我认为是每个类私有的方法,在层次结构中的每个-init之后被调用。
有人可以建议我如何解决此问题或重新设计我的设置策略?三江源。
[为了清晰起见而编辑,附加]
在继承的每个级别都需要某种形式的设置,以提供特定于该级别的数据。例如Cat特定设置。
因此,我需要的是将Cat对象完全设置为动物,猫科动物和猫。
我想一种方法是在每个级别都有不同的设置方法名称。例如setupAnimal,setupFeline,setupCat。
e.g。在动物:
-(instancetype)init
{
self = [super init];
if (self) {
[self setupAnimal];
}
return self;
}
//在Feline中:
-(instancetype)init
{
self = [super init];
if (self) {
[self setupFeline];
}
return self;
}
//在Cat:
-(instancetype)init
{
self = [super init];
if (self) {
[self setupCat];
}
return self;
}
有没有比这更好,更优选的设计?
答案 0 :(得分:1)
我认为您应该只在private_Setup
Animal
init
中调用private_Setup
方法。这就是全部。在所有子类中实现,在超类中只调用一次
您说您需要为每个子类设置不同的设置形式。当然!这就是为什么你要做的是在每个子类中实现[super private_Setup]
。实现就像你需要为每个特定的子类。它被称为压倒一切。在重写方法内调用{{1}}。您将得到您所需要的。
答案 1 :(得分:1)
您说的是super init
和超级init
来电private_Setup
,为什么您会感到惊讶?
我想你会感到惊讶,因为你希望链中的每个init
都可以调用自己的类private_Setup
。但要理解的是self
的含义取决于启动链的实例的原始类(多态)。
因此,例如,如果您在初始化Cat的过程中从动物self private_Setup
致电init
,那么 Cat&#39> { {1}}将被调用。因此,根据您所做的安排,在Cat的初始化中,Cat private_Setup
将被调用三次而其他任何一个都不会被调用。
解决方案很简单:不要使用额外的方法。初始化程序调用任何方法是一个首要的错误(而你遇到的问题是它出错的原因之一)。相反,只需在private_Setup
本身中执行设置即可。这就是它的用途。
答案 2 :(得分:0)
如果我理解正确,你暗示对private_Setup的调用发生在你所有的子类中。 init方法也是如此。
从除顶部(例如Animal)init方法之外的所有方法中删除对private_Setup的调用。只要他们都拨打[super init]
,您就可以完全调用private_Setup。