如何进行设置继承

时间:2014-03-22 14:57:26

标签: ios objective-c inheritance settings

在我的XCode项目中,我想要一些默认的设置设置,它基本上是一组变量,如GlobalTintColor,ServerUrl等。 然后,我需要为每个客户端/目标覆盖其中一些设置。 这些设置仅用于间隔使用,这意味着我不是在寻找设置捆绑类型解决方案。 我不想有重复的设置,所以某种继承似乎是正确的方法。

我在想我会创建一个包含所有默认设置的父类,然后为每个客户端创建一个子类,根据需要覆盖设置。我只是无法弄清楚我将如何加载这些设置。我认为只有需要覆盖设置的客户端才有子类。其他客户端只使用父类定义的默认设置。

但是当我在应用程序启动时加载设置时,我需要检查子类是否可用,如果没有,我只加载超类。

但是后来我遇到了设置类是什么类的问题:子类或超类? 我一直在研究类别和类聚类,但到目前为止还没有找到解决方案。 在我看来,这是很多应用程序开发人员所需要的功能。你们中有谁知道要解决这个问题的良好模式吗?

举例说明:

- (id) getAppConfigurationSettings {

    id settings;

    if ([AppConfigurationSettings class]) {
       settings = [AppConfigurationSettings class];
    } else {
       settings = [DefaultAppConfigurationSettings class];
    }

    return settings;

}

2 个答案:

答案 0 :(得分:0)

你想要这样的东西吗?

<强> “Parent.h”

@interface Parent : NSObject
@property(nonatomic,strong)UIColor *color;
@end

<强> “Parent.m”

#import "Parent.h"

@implementation Parent
-(void)setColor:(UIColor *)color{
    self.color=color;
}
@end

然后你创建另一个将继承ParentChild

的类

<强> Child.h

#import "Parent.h"
@interface Child : Parent

@end

<强> Child.m

#import "Child.h"

@implementation Child
//Override the actual color
-(void)setColor:(UIColor *)color{
    self.color=color;
}
@end

然后你可以像下面那样使用它

Parent *parent=[[Parent alloc] init];
[parent setColor:[UIColor redColor]];

Child *child=[[Child alloc] init];
[Child setColor:[UIColor blueColor]];

我希望它会给你足够的想法..

<强>更新

对于自定义初始化,您可以创建一些枚举,并按照下面的

进行相应的初始化
typedef enum {
    kParent     =       1,
    kChild      =       2
}kSettings;

-(void)updateColor:(kSettings)settingType{

    id classObj;

    switch (settingType) {
        case kParent:
            classObj=[[Parent alloc] init];
            break;

        case kChild:
            classObj=[[Child alloc] init];
            break;

        default:
            break;
    }

   [classObj setColor:[UIColor redColor]];

}

注意 - 以上代码未经测试可能不完全正确,但可以是这样。

答案 1 :(得分:0)

当我听到“基础”和“覆盖”时,我立即想到了一个类的层次结构,所以@iphonic的答案很好地完成了工作,尽管我会以稍微不同的方式设计它:

“的 BaseSettings

@interface BaseSettings : NSObject
... properties
@end

@implementation BaseSettings

- (instancetype) init {
    self = [super init];
    if (self) {
        [self constantInit];
        [self dynamicInit];
    }
}

// Put here initialization that won't be overridden
// in inherited classes
- (void) constantInit {
}

// Put here initialization that will be overridden
// in inherited classes
- (void) dynamicInit {
}

@end

“的 SettingsInheritor

@interface SettingsInheritor : BaseSettings
@end

@implementation SettingsInheritor

- (void) dynamicInit {
    // Call base method so that not overriden settings
    // are still initialized properly
    [super dynamicInit];

    // Override settings here
    ...
}

constantInit方法仅为方便起见,让您在视觉上将常量与可重写设置分开 - 因此,如果您不需要或不喜欢它,您可以将其删除。

在@ iphonic的答案中可以改进的是实际设置类是如何实例化的,所以我提出了一种不同的方法。

如上所述here,您可以使用obj_getClassList()获取所有已注册类定义的列表 - 然后您可以循环遍历所有这些定义,并检查其超类是否为BaseSettings(或者您想要调用基本设置类的任何内容),使用class_getSuperClass()isSubclassOfClass:注意:如果子类或相同的话,后一种方法返回YES,比较时要考虑的事项。

一旦找到继承自BaseSettings的类,就可以打破循环并实例化找到的类(例如使用class_createInstance())。 A(未经测试的)骨架是这样的:

int numClasses = objc_getClassList(NULL, 0);

if (numClasses > 0) {
    BOOL found = NO;
    Class settingsClass;
    Class *classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * numClasses);

    for (int index = 0; index < numClasses; ++index) {
        Class curClass = classes[index];
        Class superClass = class_getSuperclass(curClass);
        const char *superClassName = class_getName(superClass);

        if (strcmp(superClassName, "BaseSettings") == 0) {
            settingsClass = curClass;
            found = YES;
            break;
        }
    }

    if (found) {
        // Create the class instance from `settingsClass`
    }

    free(classes);
}

上述代码(大部分)<{3}}的致谢