我有一个工厂类,它有一个像
这样的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
工厂做类似的事情?
答案 0 :(得分:0)
您可以使用NSClassFromString
动态获取课程。
classesDictionary
会将键映射到类名:
classesDictionary = @{ @"KeyA" : @"NSString",
@"KeyB" : @"NSNumber" };
然后获取给定类名的Class对象:
Class theClass = NSClassFromString(classesDictionary[key]);
您可能希望执行其他检查以确保Class对象是您期望的值。 E.g。
if ([theClass isSubclassOfClass:[MyBaseClass class]])
Etc...
然后,您只需要将标头包含在公共基类中。