当然,可以定义某种将类映射到其配置值的全局字典,但这有点难看。
为什么你认为这会很丑?这是一种非常简单的方法,因为您可以将[self className]
其用作字典中的键。使其持久化也很容易,因为您可以简单地将字典存储在 NSUserDefaults 中(只要它只包含属性列表对象)。您还可以通过调用该方法让每个类默认为其超类的值,superclass
直到找到具有值的类。
+ (id)classConfigurationForKey:(NSString *)key {
if(_configurationDict == nil) [self loadConfigurations]; // Gets stored values
Class c = [self class];
id value = nil;
while(value == nil) {
NSDictionary *classConfig = [_configurationDict objectForKey:[c className]];
if(classConfig) {
value = [classConfig objectForKey:key];
}
c = [c superclass];
}
return value;
}
+ (void)setClassConfiguration:(id)value forKey:(NSString *)key {
if(_configurationDict == nil) [self loadConfigurations]; // Gets stored values
NSMutableDictionary *classConfig = [_configurationDict objectForKey:[self className]];
if(classConfig == nil) {
classConfig = [NSMutableDictionary dictionary];
[_configurationDict setObject:classConfig forKey:[self className]];
}
[classConfig setObject:value forKey:key];
}
此实现不提供检查以确保您不会越过顶级超类,因此您需要确保该类有一个值以避免无限循环。
如果要存储无法存储在属性列表中的对象,可以在访问字典时使用一种方法来回转换。这是一个访问labelColor
属性的示例,它是一个 UIColor 对象。
+ (UIColor *)classLabelColor {
NSData *data = [self classConfigurationForKey:@"labelColor"];
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
+ (void)setClassLabelColor:(UIColor *)color {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:color];
[self setClassConfiguration:data forKey:@"labelColor"];
}