Преобразовать динамическое связывание target-c в swift 2
У меня есть ситуация, когда я конвертирую проект obj-c в swift. это так
// few lazy property initializers as,
@property (nonatomic, strong) MyObject *property1;
@property (nonatomic, strong) MyObject *property2;
@property (nonatomic, strong) MyObject *property3;
...
// I keep an index value to map these into a dictionary for reference
- (NSDictionary *)indexMap
{
if (!_indexMap)
{
_indexMap = @{
@(index1) : [NSValue valueWithPointer:@selector(property1)],
@(index2) : [NSValue valueWithPointer:@selector(property2)],
...
};
}
return _indexMap;
}
// other dictionary for index to class map
- (NSDictionary *)classMap
{
return @{
NSStringFromClass(@"MyClassA") : @(index1),
NSStringFromClass(@"MyClassB") : @(index1),
NSStringFromClass(@"MyClassC") : @(index1),
NSStringFromClass(@"MyClassD") : @(index2),
NSStringFromClass(@"MyClassE") : @(index2),
NSStringFromClass(@"MyClassF") : @(index3),
...
};
}
// finally i have method to pass in the class name & it will first find corresponding index, then use the index to return the property selector.
Меня беспокоит то, что быстрый способ сделать это?
1 ответ
Один из способов сделать это - сохранить список обратных вызовов, которые выполняют инициализацию. Вот одно решение, которое является довольно гибким, хотя, конечно, возможны и более простые альтернативы:
class ComponentManager {
// Global singleton: ComponentManager.sharedManager
static let sharedManager = ComponentManager()
// Define a callback type which is used to create instances.
// This is the lazy initialiser.
typealias Constructor = () -> NSObject?
private var constructor = [String: Constructor]()
private var instances = [String: NSObject]()
func register(name: String, constructor: Constructor) {
self.constructor[name] = constructor
}
func instanceNamed(name: String) -> NSObject? {
if let instance = instances[name] {
return instance
}
guard let constructor = constructor[name] else {
return nil
}
guard let instance = constructor() else {
return nil
}
instances[name] = instance
return instance
}
}
Чтобы использовать это:
class A: NSObject {
let foo: String
init(foo: String) {
self.foo = foo
}
}
class B: NSObject {
let bar: Int
init(bar: Int) {
self.bar = bar
}
}
let manager = ComponentManager.sharedManager
// Register our classes.
// Note the callback functions which actually perform the
// initialisation, these are only called when the class is requested the
// first time.
manager.register("A") { return A(foo: "fizz") }
manager.register("B") { return B(bar: 47) }
// Create some instances
let a = manager.instanceNamed("A") as? A
let b = manager.instanceNamed("B") as? B
let a2 = manager.instanceNamed("A") as? A
print("a = \(a?.foo)")
print("a2 = \(a?.foo)")
print("b = \(b?.bar)")