Iphone 如何在初始化所有子类之后执行操作?
我有一个Objective-C类的集合,这些类通过各种不同的类在不同的深度进行子类划分。一旦初始化了整个对象(所有子类init函数都完成了),我需要运行一个“updatecache”方法,然后根据需要被子类覆盖 我的问题是: 由于我的类树有各种不同的继承深度,没有一个地方可以放置[self UpdateCache],而且我可以确定没有未初始化的子类。唯一可能的解决方案是在初始化每个类之后调用[super init],这样父类总是最后调用。我想避免这种情况,因为这违背了编写Objective-C的所有指导原则。这个问题有没有干净的解决方案 下面是一些示例代码:Iphone 如何在初始化所有子类之后执行操作?,iphone,objective-c,Iphone,Objective C,我有一个Objective-C类的集合,这些类通过各种不同的类在不同的深度进行子类划分。一旦初始化了整个对象(所有子类init函数都完成了),我需要运行一个“updatecache”方法,然后根据需要被子类覆盖 我的问题是: 由于我的类树有各种不同的继承深度,没有一个地方可以放置[self UpdateCache],而且我可以确定没有未初始化的子类。唯一可能的解决方案是在初始化每个类之后调用[super init],这样父类总是最后调用。我想避免这种情况,因为这违背了编写Objective-C的
@interface ClassA : NSObject
-(void)UpdateCache
@end
@interface ClassB : ClassA
-(void)UpdateCache
@end
@interface ClassC : ClassB
-(void)UpdateCache
@end
现在对于实现,我们需要在知道所有子类都已初始化之后,以某种方式调用UpdateCache,而不管哪个类已初始化
@implementation A
-(id)init
{
if(self = [super init])
{
// Placing [self UpdateCache] here would make it be called prior to
// B and C's complete init function from being called.
}
}
-(void)UpdateCache
{
}
@end
@implementation B
-(id)init
{
if(self = [super init])
{
// Placing [self UpdateCache] would result in UpdateChache not being
// called if you initialized an instance of Class A
}
}
-(void)UpdateCache
{
[super UpdateCache];
}
@end
@implementation C
-(id)init
{
if(self = [super init])
{
// Placing [self UpdateCache] would result in UpdateChache not
//being called if you initialized an instance of Class A or B
}
}
-(void)UpdateCache
{
[super UpdateCache];
}
@end
声明一个虚拟方法,并在需要时调用它
由于这是目标c,请参见声明一个虚拟方法,并在需要时调用它
因为这是客观的,所以请看是的,不久前我问了一个类似的问题。。。
您可以将“钩子”/“代理”添加到对象的实例中,以覆盖
-forwardInvocation:
选择器并执行所需操作。原来的问题是,我的答案是公认的。是的,我不久前问了一个类似的问题。。。
您可以将“钩子”/“代理”添加到对象的实例中,以覆盖
-forwardInvocation:
选择器并执行所需操作。最初的问题是,我对此的回答是公认的。与其在init之后立即更新缓存,不如在首次使用之前立即更新缓存?也许您可以有一个布尔实例变量cacheIsDirty
,在init中将其设置为TRUE
。然后,如果缓存是脏的,那么缓存的getter首先调用updateCache
。假设您总是使用getter,而从不直接使用实例变量(这在Objective-C中是一种很好的做法),那么客户机不应该注意到这一区别。与其在init之后立即更新缓存,不如在首次使用之前立即更新它?也许您可以有一个布尔实例变量cacheIsDirty
,在init中将其设置为TRUE
。然后,如果缓存是脏的,那么缓存的getter首先调用updateCache
。假设您总是使用getter,而从不直接使用实例变量(这在Objective-C中是一种很好的做法),那么客户端应该不会注意到这一点。您的子类是否需要唯一的init方法签名?(例如,初始化对象所需的子类特定参数)如果不是,遵循简单的类似工厂的设计模式可能会很好
添加父类/基类的示例:
+(id)buildSelf {
YourParentClass* obj = [[[self alloc] init] autorelease];
if (obj) {
[obj updateCache];
}
return obj;
}
如果需要,为所有要使用的子类添加参数
同样,如果您的子类需要支持唯一的init方法签名,那么这将不能很好地工作。您的子类需要唯一的init方法签名吗?(例如,初始化对象所需的子类特定参数)如果不是,遵循简单的类似工厂的设计模式可能会很好
添加父类/基类的示例:
+(id)buildSelf {
YourParentClass* obj = [[[self alloc] init] autorelease];
if (obj) {
[obj updateCache];
}
return obj;
}
如果需要,为所有要使用的子类添加参数
同样,如果您的子类需要支持唯一的init方法签名,那么这将不能很好地工作。我认为这不能解决我的问题。这里的问题是何时调用[self UpdateCache]函数,因为最后一个运行的init函数将根据留给init的子类的数量而变化。同一个类my或可能没有被不同的类子类化,因此没有正确的地方进行调用。如果我误解了你的答案,请让我知道并澄清这是如何解决的。我不相信这能解决我的问题。这里的问题是何时调用[self UpdateCache]函数,因为最后一个运行的init函数将根据留给init的子类的数量而变化。同一个类my或可能没有被不同的类子类化,因此没有正确的地方进行调用。如果我误解了你的答案,请让我知道并澄清这是如何解决的。冒着听起来愚蠢的风险。。。仅仅调用
[yourObj updateCache]是一个大问题吗代码>每个实例,在您分配并初始化它之后?您的描述不容易理解。“一旦整个对象初始化”?你是说整棵树吗?updateCache
是方法还是函数?它是一个类方法,还是每个子类实现的一个实例方法?为什么一个实例关心树中的其他类——也就是说,为什么你不能在每个子类的init
末尾调用这个方法?@HachiEthan——这是我目前使用的解决方案,但我正在寻找更干净的方法。事实上,我在很多地方都遇到过同样的问题,我想看看是否有解决这个问题的通用方法it@JoshCaswell-此更新缓存函数是一个非常昂贵的操作,这就是缓存其结果的原因。如果我在每个子类中调用它,那么在每一步调用它都会导致相同数据的信息生成多达4次。您所描述的仍然不清楚。你说它是一个“函数”(我想应该是“方法”)被“子类覆盖”,但你似乎也在说它只需要为整个类树调用一次。你的描述很混乱,在我最初的评论中你没有提到任何问题。请详细说明您的设计,并更具体;也许是邮递