2

我有一组 Objective-C 类,它们被各种不同的类在各种不同的深度进行子分类。初始化整个对象后(所有子类的 init 函数都已完成),我需要运行“更新缓存”方法,然后根据需要被子类覆盖。

我的问题:由于我的类树有多种不同的继承深度,没有一个地方可以放置 [self UpdateCache] 并且我可以确定没有未初始化的子类。唯一可能的解决方案是在每个类初始化之后调用 [super init],以便始终最后调用父类。我想避免这种情况,因为这违反了编写 Objective-C 的所有准则。这个问题有什么干净的解决方案吗?

这是一些示例代码:

@interface ClassA : NSObject

-(void)UpdateCache
@end

@interface ClassB : ClassA

-(void)UpdateCache
@end

@interface ClassC : ClassB

-(void)UpdateCache
@end

现在对于实现,我们需要以某种方式在我们知道所有子类都已初始化之后调用 UpdateCahce,而不管哪个类已被初始化

@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
4

4 回答 4

3

与其在初始化后立即更新缓存,不如在第一次使用之前立即更新它?也许您可以在 init 中cacheIsDirty设置一个布尔实例变量。然后,如果缓存脏TRUE,您的缓存获取器首先调用。updateCache假设您总是使用 getter 而从不直接使用实例变量(这在 Objective-C 中是一种很好的做法),客户端应该不会注意到差异。

于 2012-06-13T18:17:51.020 回答
1

您的子类是否需要唯一的 init 方法签名?(例如,初始化对象所需的子类特定参数)如果没有,遵循简单的类似工厂的设计模式可能会很好。

添加父类/基类的示例:

+(id)buildSelf {
    YourParentClass* obj = [[[self alloc] init] autorelease];
    if (obj) {
        [obj updateCache];
    }
    return obj;
}

如果需要,向它添加参数,供所有子类使用。

同样,如果您的子类需要支持唯一的 init 方法签名,那么这将无法正常工作。

于 2012-06-13T18:44:50.763 回答
0

声明一个虚方法并在需要时调用它......

并且由于这是目标 c,请参阅在 Objective-C 中实现纯虚拟方法

于 2012-06-13T17:46:02.260 回答
0

是的,不久前我问了一个类似的问题……您可以将“挂钩”/“代理”添加到对象的实例中,以覆盖-forwardInvocation:选择器并执行您想要的操作。最初的问题是here,我对此的回答是被接受的。

于 2012-06-13T17:51:44.793 回答