工厂模式 - 如何在工厂类中生成空类声明

时间:2014-05-25 09:23:13

标签: objective-c dynamic runtime forward-declaration

我有一个工厂类,它有一个像

这样的init方法
+(instancetype)initWithDictionary:(NSDictionary);

在实施中像

@class ClassA,ClassB,ClassC,.... lots and lots of classes; // like 20+
@implementation

+(instancetype)initWithDictionary:(NSDictionary *)dictionary
{
    NSString *factoryKey = dictionary[@"some useful key to create a class"];
    Class theCorresondingClass = [self classForKey:factoryKey];
    return [[theCorrespondingClass alloc] initWithDictionary:dictionary];
}

-(Class)classForKey:(NSString *)key
{
    static NSDictionary *classesDictionary;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSArray *classes = [[ClassA class],[ClassB class],[....],.....]; // the 20+ class from above
        NSArray *keysForClasses = [@"KeyA",@"KeyB,....]; // the 20 keys for the classes
        classesDictionary = [NSDictionary dictionaryWithObjects:classes forKeys:keysForClasses];
    }
    return classesDictionary[key];

}

问题是我从前向声明中分配init(在字典中是一个错误)这是一个编译时错误 - 我认为可能的唯一解决方案是将所有类导入工厂 - 这似乎是一个糟糕的举动 - 因为理想情况下我希望工厂支持其他类的注册 - 这样它将在运行时创建这些类 - 或者在工厂中定义所有类 - 这看起来更糟 -

问题是所有类都从公共基类继承,所以我知道在运行时它将被正确定义(alloc init方法) -

是否有某种方法可以对类名进行@dynamic定义?也许创建一个宏来在工厂类中存根一个空类?

苹果如何在NSTextCheckingResult.h工厂做类似的事情?

1 个答案:

答案 0 :(得分:0)

您可以使用NSClassFromString动态获取课程。

classesDictionary会将键映射到类名:

classesDictionary = @{ @"KeyA" : @"NSString",
                       @"KeyB" : @"NSNumber" };

然后获取给定类名的Class对象:

Class theClass = NSClassFromString(classesDictionary[key]);

您可能希望执行其他检查以确保Class对象是您期望的值。 E.g。

if ([theClass isSubclassOfClass:[MyBaseClass class]])
    Etc...

然后,您只需要将标头包含在公共基类中。