Ios 如何使子类将属性初始化为正确的类?
我有一个名为Ios 如何使子类将属性初始化为正确的类?,ios,objective-c,cocoa-touch,Ios,Objective C,Cocoa Touch,我有一个名为SPPanelManager的类,它具有另一个名为SPPanelSettingsManager的类的属性。SPPanelManager在其-init方法中具有以下功能: self.settingsManager = [[SPPanelSettingsManager alloc] init]; SPPanelManager的目的是子类化,子类在我的整个应用程序中使用。例如,有SPGreetingManager。在SPGreetingManager的.h文件中,我声明: @proper
SPPanelManager
的类,它具有另一个名为SPPanelSettingsManager
的类的属性。SPPanelManager在其-init
方法中具有以下功能:
self.settingsManager = [[SPPanelSettingsManager alloc] init];
SPPanelManager
的目的是子类化,子类在我的整个应用程序中使用。例如,有SPGreetingManager
。在SPGreetingManager
的.h文件中,我声明:
@property (nonatomic, strong) SPGreetingSettingsManager *settingsManager;
这使得settingsManager属于正确的类。问题是当初始化SPGreetingManager
子类时,它调用上面的init方法,并将setingsmanager初始化为sppanelsetingsmanager
类,而不是spgreetingsetingsmanager
我如何才能让它初始化为该属性的正确类,而不必在每个子类中重新编写init代码?超级类(SPPanelManager
)必须知道具体面板管理器想要用作设置管理器的类
Apple使用以下方法将CALayers与UIView进行匹配:
基类声明一个类方法,该方法返回具体的sppanelSettings管理器子类:
// in SPPanelManager.h
+ (Class)settingsManagerClass;
。。。哪些子类重写以返回其自定义类:
// in SPGreetingManager.m
+ (Class)settingsManagerClass
{
return [SPGreetingSettingsManager class];
}
现在,超类可以按如下方式实例化设置管理器:
self.settingsManager = [[[[self class] settingsManagerClass] alloc] init];
另一个常见的解决方案是使用命名约定。只需匹配类的名称:SPGreetingManager
有一个spgreetingsetingsmanager
根据定义,每个…管理器必须有一个匹配的…设置管理器
// 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];
优点是子类不必重写公共方法来声明类类型。另一方面,它似乎有点混淆了正在发生的事情
此外,上面的代码强制类之间建立一对一的关系。无法重用任何设置控制器。SPPanelManager是您开发的类吗?只需给它一个init,其中包含设置实例的参数。这是self.setingsmanager=[[SPPanelSettingsManager alloc]init];在您的SPPanelManager init方法中?使用spgreetingsetingsmanager
和sppanelsetingsmanager
的基类作为setingsmanager
属性类,然后在SPPanelManager
子类不提供该类时,通过断言在某些方法中请求特定的子类如何?或者在这种情况下,只需为设置管理器
初始化使用默认类。我建议使用-initWithPanelManager:(SPPanelManager*)管理器
方法来正确插入Dedency类。