4

我有一个名为 的类SPPanelManager,它具有另一个类的属性,名为SPPanelSettingsManager。SPPanelManager 在它的-init方法中有以下内容:

self.settingsManager = [[SPPanelSettingsManager alloc] init];

的目的SPPanelManager是子类化,子类在我的整个应用程序中使用。例如,有SPGreetingManager. 在 .h 文件中SPGreetingManager,我声明:

@property (nonatomic, strong) SPGreetingSettingsManager *settingsManager;

这使得 settingsManager 属于正确的类。问题是SPGreetingManager子类初始化的时候,调用了上面的init方法,把settingsManager初始化为SPPanelSettingsManager类,而不是SPGreetingSettingsManager.

我怎样才能让它初始化为该属性的正确类,而不必在每个子类中重新编写初始化代码?

4

3 回答 3

8

超类 ( SPPanelManager) 必须知道具体面板管理器想要使用哪个类作为settingsManager.

Apple 使用以下方法将 CALayers 与 UIViews 匹配:

基类声明了一个返回具体SPPanelSettingsManager子类的类方法:

// in SPPanelManager.h
+ (Class)settingsManagerClass;

...覆盖哪些子类以返回其自定义类:

// in SPGreetingManager.m
+ (Class)settingsManagerClass
{
    return [SPGreetingSettingsManager class];
}

现在超类可以实例化设置管理器,如下所示:

self.settingsManager = [[[[self class] settingsManagerClass] alloc] init];
于 2013-08-15T17:08:51.330 回答
1

另一种常见的解决方案是使用命名约定。只需匹配类的名称:SPGreetingManager有一个SPGreetingSettingsManager.

根据定义,每个 ...Manager 必须有一个匹配的 ...SettingsManager。

// in SPPanelManager.m init
NSString *className = NSStringFromClass([self class]);
className = [className stringByReplacingOccurrencesOfString:@"Manager"
                                                 withString:@"SettingsManager"];
Class settingsManagerClass = NSClassFromString(className);
NSAssert(settingsManagerClass != Nil, @"no settings manager class found");

self.settingsManager = [[[settingsManagerClass settingsManagerClass] alloc] init];

优点是子类不必重写通用方法来声明类类型。另一方面,它可能看起来有点混淆正在发生的事情。

此外,上面的代码强制类之间建立一对一的关系。没有设置控制器可以重复使用。

于 2013-08-15T17:11:30.560 回答
0

SPPanelManager 是您开发的类吗?只需给它一个带有设置实例参数的init。

于 2013-08-15T19:37:41.763 回答