Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何在初始化所有子类之后执行操作?_Iphone_Objective C - Fatal编程技术网

Iphone 如何在初始化所有子类之后执行操作?

Iphone 如何在初始化所有子类之后执行操作?,iphone,objective-c,Iphone,Objective C,我有一个Objective-C类的集合,这些类通过各种不同的类在不同的深度进行子类划分。一旦初始化了整个对象(所有子类init函数都完成了),我需要运行一个“updatecache”方法,然后根据需要被子类覆盖 我的问题是: 由于我的类树有各种不同的继承深度,没有一个地方可以放置[self UpdateCache],而且我可以确定没有未初始化的子类。唯一可能的解决方案是在初始化每个类之后调用[super init],这样父类总是最后调用。我想避免这种情况,因为这违背了编写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次。您所描述的仍然不清楚。你说它是一个“函数”(我想应该是“方法”)被“子类覆盖”,但你似乎也在说它只需要为整个类树调用一次。你的描述很混乱,在我最初的评论中你没有提到任何问题。请详细说明您的设计,并更具体;也许是邮递